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