MST

星途 面试题库

面试题:Go语言中如何使用标准库实现简单的AES加密

请描述在Go语言中,使用标准库`crypto/aes`实现AES加密(如AES - 128 - CBC模式)的主要步骤,并给出简单的代码示例,包括密钥生成、初始化向量设置等关键部分。
10.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 主要步骤

    • 生成密钥:AES - 128 - CBC模式需要16字节(128位)的密钥。可以通过多种方式生成密钥,比如从安全的随机数生成器获取。
    • 设置初始化向量(IV):CBC模式需要一个与块大小相同长度的IV,AES块大小为16字节,所以IV也是16字节。
    • 创建加密器:使用crypto/aes库的NewCipher函数创建一个AES加密器。
    • 填充数据:由于AES加密要求数据长度是块大小的整数倍,所以需要对数据进行填充,常用的填充方式有PKCS7填充。
    • 执行加密:调用加密器的CryptBlocks方法对数据进行加密。
  2. 代码示例

package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "fmt"
)

// PKCS7填充
func pkcs7Padding(data []byte, blockSize int) []byte {
    padding := blockSize - len(data)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(data, padtext...)
}

// PKCS7去填充
func pkcs7UnPadding(data []byte) []byte {
    length := len(data)
    unpadding := int(data[length - 1])
    return data[:(length - unpadding)]
}

func aesEncryptCBC(plaintext, key, iv []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err!= nil {
        return nil, err
    }
    blockSize := block.BlockSize()
    plaintext = pkcs7Padding(plaintext, blockSize)
    mode := cipher.NewCBCEncrypter(block, iv)
    ciphertext := make([]byte, len(plaintext))
    mode.CryptBlocks(ciphertext, plaintext)
    return ciphertext, nil
}

func aesDecryptCBC(ciphertext, key, iv []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err!= nil {
        return nil, err
    }
    mode := cipher.NewCBCDecrypter(block, iv)
    plaintext := make([]byte, len(ciphertext))
    mode.CryptBlocks(plaintext, ciphertext)
    plaintext = pkcs7UnPadding(plaintext)
    return plaintext, nil
}

func main() {
    key := []byte("1234567890123456") // 16字节密钥
    iv := []byte("1234567890123456")  // 16字节IV
    plaintext := []byte("Hello, World!")

    encrypted, err := aesEncryptCBC(plaintext, key, iv)
    if err!= nil {
        fmt.Println("Encryption error:", err)
        return
    }
    fmt.Printf("Encrypted: %x\n", encrypted)

    decrypted, err := aesDecryptCBC(encrypted, key, iv)
    if err!= nil {
        fmt.Println("Decryption error:", err)
        return
    }
    fmt.Printf("Decrypted: %s\n", decrypted)
}