1 回答

TA貢獻(xiàn)1883條經(jīng)驗(yàn) 獲得超3個(gè)贊
GCM 與 CBC 模式不同。密鑰是十六進(jìn)制編碼的,所以一個(gè) 32 字節(jié)的字符串代表一個(gè) 16 字節(jié)(或 128 位)的密鑰。
在 CBC 模式下,明文必須被填充,以便它是塊大小的倍數(shù)。PHP 的 openssl_encrypt 自動(dòng)執(zhí)行此操作(使用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 關(guān)注
- 257 瀏覽
添加回答
舉報(bào)