【发布时间】:2018-01-24 12:45:03
【问题描述】:
在 PHP 中,mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); 返回值 32,因此显然表示 AES-256 需要 32 字节的初始化向量。但这是骗人的,正如comments for mcrypt_encrypt中所说:
另外,
MCRYPT_RIJNDAEL_256不是 AES-256,它是 Rijndael 分组密码的不同变体。如果你想在 mcrypt 中使用 AES-256,你必须使用带有 32 字节密钥的MCRYPT_RIJNDAEL_128。 OpenSSL 使您使用的模式更加明显(即“aes-128-cbc”与“aes-256-ctr”)。
当然,对于 32 字节的 IV,以下示例在 Go 中不起作用(它会导致恐慌)。
score := decodePost(c.PostForm("score"))
iv := decodePost(c.PostForm("iv"))
aesKey := getAESKey()
baseAES, err := aes.NewCipher([]byte(aesKey))
if err != nil {
c.AbortWithError(500, err)
return
}
block := cipher.NewCBCDecrypter(baseAES, []byte(iv))
block.CryptBlocks(score, score)
引用crypto/cipher的文档:
iv 的长度必须与 Block 的块大小相同,并且必须与用于加密数据的 iv 匹配。
(当然还有AES block size in Go is 16 bytes)。
那么,最后,如何在 Go 中解密这样的字符串?
【问题讨论】:
-
当然最好的解决方案是在另一边将 Rijndael 块大小更改为 128 位,并消除现在和将来的互操作性问题。
-
那将是理想的,但不幸的是我不能这样做,因为我无法控制对方(而且我没有简单的方法来获得它)。
-
Rijndael-256,正如明确指出的那样,不是 AES。是瑞恩达尔。您需要为您的 go 代码实现此功能。您需要 32 字节 IV 的原因是因为 Rijndael-256 的块大小为 256 位。
标签: php encryption go aes