Pycrypto AES 256 初始化向量大小

4 投票
1 回答
11067 浏览
提问于 2025-04-17 07:29

这是我的情况,我有一个使用AES256加密的PHP脚本,采用的是CBC模式。这个脚本里的密钥和初始化向量(IV)的大小都是32个字节。

data= '123456789abcdef' 
from Crypto.Cipher import AES
a = AES.new('oqufXQ(?bc=6_hR2I3sMZChDpb6dDlw4',2,'fOaiIOkD8*9Xeu_s4_bb87Ox_UG+D9GA')
print a.encrypt(data)

然后我遇到了一个错误。

<type 'exceptions.ValueError'>: IV must be 16 bytes long
Traceback (most recent call last):
  File "/base/data/home/apps/s~xxxxxxx/1.155074369696961822/main.py", line 4, in <module>

这是我能正常工作的PHP代码。

 echo base64_encode(encrypt('0123456789abcdef'))  ;


 function encrypt($data)
  {
    return mcrypt_encrypt(MCRYPT_RIJNDAEL_256 ,'oqufXQ(?bc=6_hR2I3sMZChDpb6dDlw4', $data , MCRYPT_MODE_CBC, utf8_encode('fOaiIOkD8*9Xeu_s4_bb87Ox_UG+D9GA') );
  }

我不能改变初始化向量的大小。

需要注意的是,我对Python不是很熟悉,只是想找到一种加密数据的方法,因为这会在一个应用引擎上使用。

1 个回答

11

啊哈!

关于“256”指的是什么,大家有不同的看法。

AES的块大小是固定的,都是128位,所以“AES 256”其实是指128位的块,256位的密钥,还有14轮加密过程。

但是,Rijndael算法允许密钥大小和块大小都可以变化。MCRYPT_RIJNDAEL_256是指块大小设置为256位的Rijndael(我不知道有多少轮)。所以它确实需要一个32字节的初始化向量(IV)。你的PHP脚本实际上并没有使用AES 256。

这一点在https://bugs.php.net/bug.php?id=47125中得到了确认——报告这个问题的人认为这是PHP mcrypt的一个bug,而PHP认为这是libmcrypt的bug,但其实这并不是bug,因为libmcrypt确实有说明MCRYPT_RIJNDAEL_256的意思(至少在Linux的mcrypt手册页中有说明,我在网上找不到libmcrypt的实际文档)。这两者的含义并不相同。

所以,你在加密和解密时使用的算法虽然有关系,但实际上可能是完全不同的。

坏消息是,在PyCrypto中似乎没有Crypto.Cipher.RIJNDAEL这个选项。如果你能在PHP脚本中将256位的密钥传递给MCRYPT_RIJNDAEL_128,那就可以算作AES 256了(谢谢Paŭlo)。

撰写回答