如何在PyCrypto AES CTR模式下设置块大小

3

我正在尝试通过Python中的PyCrypto库实现AES加密。

我从用户读取密码和从文件读取盐。 然后,我调用PBKDF2从文本密码生成密钥。

PBKDF2(self.master_password, salt, 32)

我会使用Random.get_random_bytes生成一个IV。

IV = Random.get_random_bytes(len(key))

我接下来使用 Crypto.Util 包创建了一个计数器 Counter。
ctr = Counter.new(32, IV)

然后我创建了一个AES对象

e = AES.new(key, AES.MODE_CTR, counter=ctr)

然而,当我调用e进行加密时
e.encrypt(user_name)

我遇到了以下错误

CTR counter function returned string not of length 16

根据我的理解,这个错误意味着块密码是16字节,这与我在https://www.dlitz.net/software/pycrypto/api/current/Crypto.Cipher.AES-module.html找到的文档相符。我尝试通过以下方式创建AES对象将其更改为32字节块大小。
AES_Encryptor = AES.new(key, AES.MODE_CTR, counter=ctr, block_size=32)

但是我遇到了以下错误。
'block_size' is an invalid keyword argument for this function

如果有人能指引我正确的方向,那就太好了。

为什么需要256位的块大小? - zaph
这是我项目描述的一部分。 - Mitziu Echeverria
好的,描述有误,正如Artjom所说,AES只有一个块大小,即128位。您需要更改项目说明。使用256位块大小并且使用256位块大小的Rijndael并没有像AES那样经过广泛验证,因此没有很好的理由使用它。 - zaph
1个回答

4
AES是一种分组密码,其固定分组大小为128位(16字节)。它有三种有效的密钥长度,分别为128位、192位和256位。CTR模式下用于防止重复计数的随机数,有时也称为IV,需要最大与块大小相等,即16字节。

如果您想要256位的块大小,则无法使用AES。还有其他一些允许256位块大小的算法,如Rijndael,但在pycrypto中没有实现该算法。AES是Rijndael的子集。

通常,我们会生成64位或96位的随机数作为CTR模式的随机数,以便对加密的块数进行一定的控制以避免计数碰撞。

nonce = Random.get_random_bytes(8)  # 8 bytes
ctr = Counter.new(64, nonce)        # 64 bits remaining

或者

nonce = Random.get_random_bytes(12) # 12 bytes
ctr = Counter.new(32, nonce)        # 32 bits remaining

对于64位的nonce,在遇到问题之前,您最多可以加密264个数据块。这比世界上任何数据都要多,但问题在于,通过随机选择nonce,由于生日悖论,您在使用相同密钥进行232次加密后,有1的概率会发生nonce碰撞。
对于96位的nonce,您最多可以加密232个数据块,大约为68GB的数据,但是您获得nonce碰撞的机会要低得多。
Nonce不是机密信息,因此您可以将其与密文一起发送。通常,它只是附加在密文前面,并在解密之前切掉。由于您知道它应该有多长,因此您知道可以切掉多少。

感谢您的解释,确实让我更加清楚了。 - Mitziu Echeverria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接