1 回答
TA贡献1883条经验 获得超3个赞
GCM 与 CBC 模式不同。密钥是十六进制编码的,所以一个 32 字节的字符串代表一个 16 字节(或 128 位)的密钥。
在 CBC 模式下,明文必须被填充,以便它是块大小的倍数。PHP 的 openssl_encrypt 自动执行此操作(使用PKCS#5/7),但在 Go 中必须明确完成。
综上所述,我们最终得到了文档中 CBC 加密示例的轻微变化:
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/hex"
"io"
)
func encrypt(plaintext, key16 string) string {
padded := pkcs7pad([]byte(plaintext), aes.BlockSize)
key, err := hex.DecodeString(key16)
if err != nil {
panic(err)
}
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
buffer := make([]byte, aes.BlockSize+len(padded)) // IV followed by ciphertext
iv, ciphertext := buffer[:aes.BlockSize], buffer[aes.BlockSize:]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, padded)
return base64.StdEncoding.EncodeToString(buffer)
}
func pkcs7pad(plaintext []byte, blockSize int) []byte {
padding := blockSize - len(plaintext)%blockSize
return append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...)
}
- 1 回答
- 0 关注
- 229 浏览
添加回答
举报