1 回答
TA贡献1806条经验 获得超5个赞
首先,两种代码的密文是相同的。但是,Golang 代码中的密文转换不正确。
在 C# 代码中,的内容以十进制格式打印。要在 Golang 代码中获得等效输出,还必须以十进制格式打印的内容,这可以通过以下方式轻松实现:byte[][]byte
fmt.Println("ciphertext ", ciphertext)
并生成以下输出:
ciphertext [110 150 8 224 44 118 15 182 248 172 105 14 61 212 219 205 216 31 76 112 179 76 214 154 227 112 159 176 24 61 108 100]
并且与 C# 代码的输出相同。
在当前代码中,首先使用以下代码对密文进行编码:
encrypted = hex.EncodeToString(ciphertext)
转换为十六进制字符串,可通过以下方式轻松验证:
fmt.Println("encrypted (hex)", encrypted)
生成以下输出:
encrypted (hex) 6e9608e02c760fb6f8ac690e3dd4dbcdd81f4c70b34cd69ae3709fb0183d6c64
将十六进制字符串转换为 with 时,将进行 Utf8 编码,该编码将数据大小加倍,作为输出::[]byte[]byte(encrypted)
fmt.Println("encrypted", []byte(encrypted))
在当前代码中显示:
encrypted [54 101 57 54 48 56 101 48 50 99 55 54 48 102 98 54 102 56 97 99 54 57 48 101 51 100 100 52 100 98 99 100 100 56 49 102 52 99 55 48 98 51 52 99 100 54 57 97 101 51 55 48 57 102 98 48 49 56 51 100 54 99 54 52]
CBC是一种块密码模式,即明文长度必须是块大小的整数倍(AES为16字节)。如果不是这种情况,则必须应用填充。C# 代码隐式使用 PKCS7 填充。这也是不满足长度条件的明文也被处理的原因。
相反,在Golang中,必须显式完成代码填充,这是通过实现PKCS7填充的方法完成的。该方法的第二个参数是块大小,对于 AES,块大小为 16 个字节。对于此参数,实际上应该传递。目前,在此处传递,对于 AES-256,其大小为 32 字节。尽管这与当前明文长度的 C# 代码兼容,但对于任意明文长度(例如 32 个字节)不兼容。PKCS5Padding()PKCS5Padding()aes.BlockSizelen(key)
以下代码包含上面说明的更改和输出:
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
)
func main() {
query := "csharp -> golang"
key := []byte("12345678901234567890123456789012")
iv := []byte("1234567890123456")
if len(key) != 32 {
fmt.Printf("key len must be 16. its: %v\n", len(key))
}
if len(iv) != 16 {
fmt.Printf("IV len must be 16. its: %v\n", len(iv))
}
var encrypted string
toEncodeByte := []byte(query)
fmt.Println("query =>", query)
fmt.Println("toEncodeByte = ", toEncodeByte)
toEncodeBytePadded := PKCS5Padding(toEncodeByte, aes.BlockSize)
// aes
block, err := aes.NewCipher(key)
if err != nil {
fmt.Println("CBC Enctryping failed.")
}
ciphertext := make([]byte, len(toEncodeBytePadded))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, toEncodeBytePadded)
encrypted = hex.EncodeToString(ciphertext)
// end of aes
fmt.Println("encrypted", []byte(encrypted))
fmt.Println("encrypted (hex)", encrypted)
fmt.Println("ciphertext", ciphertext)
fmt.Println("aes.BlockSize", aes.BlockSize)
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := (blockSize - len(ciphertext)%blockSize)
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
- 1 回答
- 0 关注
- 83 浏览
添加回答
举报