【发布时间】:2019-11-17 11:45:49
【问题描述】:
我尝试在 go 中重写一些用 php5.6 (CodeIgniter) 制作的旧代码,但我在 go 中用解密来敲我的脑袋。我设法从 php 解码 MCRYPT_RIJNDAEL_128,其中 iv 大小为 16 个字符,但我不能在 256 上执行 - iv 是 32。我不想使用 go_mcrypt 因为这对 libcrypt 标头很严格,所以我尝试了使用带有 CBC 模式的 go classic encrypt libs AES 密码,但在 256 上它抱怨 IV 长度...... php IV 有 32 个字符而不是预期的 16 个......
php部分运行良好...
private $CIPHER_KEY = "12345678901234567890123456789012";
private function Encrypt($toEncrypt=null){
$iv_size = $this->ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = $this->ivKey = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$this->B64IV = base64_encode($iv);
return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->CIPHER_KEY, $toEncrypt, MCRYPT_MODE_CBC, $iv));
}
这是 PHP 的结果:
KEY: 12345678901234567890123456789012
IV: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1w=
ENC: Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA==
IV Size: 32
IV 包含在加密文本中...(并且有 32 个字符)
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); return 32
func main(){
key := []byte("12345678901234567890123456789012")
iv,_ := base64.StdEncoding.DecodeString("Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1w=")
encText,_ := base64.StdEncoding.DecodeString("Egu4tSySXluBLi5dcMzHbZHVSOS7jdNwUKUFlZ8dL1yATFjg26/Nav7cWtlJJL3djhUCND6KV8r/JL7owboKFA==")
// iv := encText[:32] // also tried to get the iv from encoded string
fmt.Printf("Key Len: %d\nIV Len: %d\nENC Len: %d\n",len(key),len(iv),len(encText))
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
if len(encText) < aes.BlockSize {
panic("cipherText too short")
}
cipherText := encText[32:]
if len(cipherText)%aes.BlockSize != 0 {
panic("cipherText is not a multiple of the block size")
}
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(cipherText, cipherText)
cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize)
fmt.Printf("Dec: %s\n",cipherText)
}
关键镜头:32 四连:32 ENC 长度:64 恐慌:cipher.NewCBCDecrypter:IV 长度必须等于块大小
goroutine 1 [运行中]: crypto/cipher.NewCBCDecrypter(0x10e7c20, 0xc00009a030, 0xc00008a000, 0x20, 0x42, 0x0, 0x0)
IV 大小为 32,但块大小为 16。
【问题讨论】:
-
OK - 我重新阅读了文档,AES-256 仅使用 128 字节 IV(16 个字符)。AES 是 Rijndael 的变体,具有 128 位的固定块大小,密钥大小为 128、192 或 256 位。 Rijndael 文档指定块和密钥大小为 32 位的倍数,最小为 128 位,最大为 256 位,因此混淆 AES 不是 RIJNDAEL - 只是一个变体。我想唯一的解决方案是解密 php 中的敏感数据并使用 128 字节 IV 对其进行加密。任何人都知道另一个库 - 与 RIJNDAEL 250 兼容,适用于 256 字节(32 个字符)的 IV?
标签: php go aes rijndael cbc-mode