【问题标题】:Pycrypto aes 256 Initialization vector sizePycrypto aes 256 初始化向量大小
【发布时间】:2011-12-01 17:37:25
【问题描述】:

这是我有一个使用 aes256 ,CBC 的 php 脚本的情况 密钥和 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') );
  }

我无法更改 IV 大小

请注意,我对 Python 不是很熟悉,只需要一种加密数据的方法,因为它将是一个 appengine 。

【问题讨论】:

  • 您不能不更改 IV 大小。 AES 256 是块大小为 16 的块密码,因此当用于任何使用 IV 的标准密码模式时,IV 是一个块大,即 16 个字节。
  • 我的 php 脚本使用 32 字节的随机字符串作为 IV,我做错了什么吗? mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);返回 32
  • 对不起,我不知道。我希望 CBC 模式下的 AES256 使用一个 IV 块,在加密该明文之前与第一个明文块进行异或。如果 mcrypt 做了一些不同的事情,涉及另外 16 个字节的 IV,那么它不会像 I 所理解的那样使用 CBC 密码模式,这意味着它不会与按我的方式工作的实现互操作明白它。我并没有声称我的理解有什么大不了的,但它与您从 pycrypto 获得的错误消息相匹配,所以我认为密码模式在某种程度上不匹配。
  • 哦,我想要检查的一件事是 mcrypt 是否使用 pbkdf2 或其他东西来操纵你给它的所谓的 IV,并将其结果的一部分用作真正的 IV。跨度>
  • 添加了加密的php代码,我不认为它使用pbkdf2来派生新的IV,不确定php是否默认这样做

标签: python google-app-engine aes pycrypto


【解决方案1】:

啊哈!

对于“256”的含义存在不同的看法。

AES 的块大小固定为 128 位,因此“AES 256”表示 128 位块、256 位密钥、14 轮。

但是,Rijndael 允许密钥大小和块大小发生变化。 MCRYPT_RIJNDAEL_256 指的是 Rijndael,block size 设置为 256(我不知道有多少轮)。所以它确实需要一个 32 字节的 IV。您的 PHP 脚本不是使用 AES 256。

这在https://bugs.php.net/bug.php?id=47125 中得到了证实——记者认为它是 PHP mcrypt 中的一个错误,PHP 认为它是 libmcrypt 中的一个错误,但这不是一个错误,因为 libmcrypt 确实记录了MCRYPT_RIJNDAEL_256 的含义(至少在 linux mcrypt 的手册页确实如此,我的 Google-fu 未能找到 libmcrypt 的任何实际文档)。那件事恰好与 AES 256 的含义不同。

因此,您正在使用虽然相关但可能完全不同的密码进行加密和解密。

坏消息是 PyCrypto 中似乎没有 Crypto.Cipher.RIJNDAEL。如果您可以在 PHP 脚本中将 256 位密钥传递给 MCRYPT_RIJNDAEL_128,那将是 AES 256(感谢 Paŭlo)。

【讨论】:

  • @user80287。 AES 128、192 和 256 是配置 Rijndael 的三种特定方式。但是,Rijndael 有比这些更多的配置选项。因此,如果您有一个完整的 Rijndael 实现,那么您可以轻松执行 AES,但实现者不一定要编写一个完全灵活的 Rijndael,他们可能会将其缩减到所需的部分。因此,AES 实现不一定支持 128 以外的块大小。
  • 哇!感谢您的解释。我认为 AES 和 Rijndael 具有相同的实现,我无法控制密钥或 IV,我的意思是我无法更改 IV。所以我需要使用其他库,再次感谢。
  • @user80287, Steve:实际上,MCRYPT_RIJNDAEL_128(“具有 128 位块大小的 Rijndael”)是 AES 的所有三个版本 - 只需传递正确大小的密钥,它就会选择正确的算法( AES-128、AES-192、AES-256)。 (不过,如果您无法更改 PHP 脚本,这将无济于事。)
猜你喜欢
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多