pycrypto无法复现AES(CFB模式)的NIST测试向量

3
这个小的 Python 程序应该使用 AES 在 CFB 模式下,使用 128 位密钥将 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 测试向量 (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的实现是正确的,因为它的输出与在线工具(例如此页面)一致。显然,是我在错误地使用工具……
有人知道如何使用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

我使用PyCrypto 2.6.0得到了和你一样的结果... - undefined
2个回答

4
你的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”的内容。


啊,那就有道理了! - undefined
谢谢你查看文档。现在一切都按预期工作。非常感谢。 - undefined

-1

当我使用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

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