pycrypto不会为AES(CFB模式)重现NIST测试向量

时间:2017-08-18 16:18:25

标签: python encryption aes pycrypto

这个小python程序应该使用128位密钥在CFB模式下使用AES加密 plain cipher

from Crypto.Cipher import AES

#            1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
key   = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
iv    = b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
plain = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

aes = AES.new(key, AES.MODE_CFB, iv)
cipher = aes.encrypt(plain)

print(' '.join('{:2x}'.format(b) for b in cipher))

我从NIST test vectors之一(CFB128VarTxt128.rsp)中获取了这个密钥,IV和普通密码组合。对于这个特殊的组合,我期待密码:

3a d7 8e 72 6c 1e c0 2b 7e bf e9 2b 23 d9 ec 34

但pycrypto计算

3a 81 e1 d4 b8 24 75 61 46 31 63 4b 5c 79 d6 bc

第一个字节是正确的,而其他不匹配。我也尝试了不同的测试向量,但结果保持不变。除第一个字节外,所有字节都不匹配。

我很确定,NIST测试向量是有效的,因为我之前在使用带有Crypto ++的AES时使用它们,我也很确定pycrypto的实现是正确的,因为它的输出与{{{}等在线工具一致。 3}}。显然,是我,是以错误的方式使用这些工具......

有没有人有线索,如何用pycrypto重现NIST测试载体?

这是NIST的例子

# CAVS 11.1
# Config info for aes_values
# AESVS VarTxt test data for CFB128
# State : Encrypt and Decrypt
# Key Length : 128
# Generated on Fri Apr 22 15:11:53 2011
...
COUNT = 0
KEY = 00000000000000000000000000000000
IV = 80000000000000000000000000000000
PLAINTEXT = 00000000000000000000000000000000
CIPHERTEXT = 3ad78e726c1ec02b7ebfe92b23d9ec34

2 个答案:

答案 0 :(得分:3)

您在AES.new(...)来电中缺少关键字参数segment_size。这是反馈大小,默认为8.如果您的代码行更改为

aes = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

你得到了正确的结果。

正如文档中所述:

  

segment_size(整数) - (仅限MODE_CFB)。位数   明文和密文是分段的。它必须是8的倍数。   如果指定0或未指定,则假定为8。

您的结果与NIST文档中可能标记为“CFB8”的内容相对应。

答案 1 :(得分:0)

使用AES.MODE_CFB时,我也得到与您相同的结果,但是当我使用AES.MODE_CBC时,我得到了您期望的结果。

from Crypto.Cipher import AES

def show(b):
    print(*['{:02x}'.format(u) for u in b])

key   = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
iv    = b'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
plain = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

crypto = AES.new(key, AES.MODE_CBC, iv)
cipher = crypto.encrypt(plain)
show(cipher)

# We need a fresh AES object to decrypt
crypto = AES.new(key, AES.MODE_CBC, iv)
decoded = crypto.decrypt(cipher)
show(decoded)

<强>输出

3a d7 8e 72 6c 1e c0 2b 7e bf e9 2b 23 d9 ec 34
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00