想知道将 openssl 的 AES_128_CTR 加密转换为 PyCrypto 的正确方法。
首先,我通过 openssl 进行了加密,如下所示:
openssl enc -aes-128-ctr -in input.mp4 -out output.openssl.mp4 -K 7842f0a1ebc38f44e3e0c81943f68582 -iv d01f40dfc8ec8cd9
然后,我尝试通过 PyCrypto 做同样的事情:
from Crypto.Cipher import AES
from Crypto.Util import Counter
key = '7842f0a1ebc38f44e3e0c81943f68582'
iv = 'd01f40dfc8ec8cd9'
ctr_e = Counter.new(128, initial_value=int(iv, 16))
encryptor = AES.new(key.decode('hex'), AES.MODE_CTR, counter=ctr_e)
with open('output.pycrypto.mp4', 'wb') as fout:
with open('input.mp4', 'rb') as fin:
fout.write(encryptor.encrypt(fin.read()))
我认为它们应该是相似的,但事实并非如此:
diff output.openssl.mp4 output.pycrypto.mp4
Binary files output.openssl.mp4 and output.pycrypto.mp4 differ
OpenSSL 的行为符合预期(幸运的是,命令行中缺少该事实的文档)并使用给定的 IV 作为大端计数器的最左边字节。换句话说,给出的字节是最重要的16 字节计数器的一部分。问题中的代码使用 IV 作为初始计数器值,即它被解释为最不重要柜台的一部分。
现在我花了一些时间来修复 Python 代码,因为有两个问题Counter
我必须解决的问题:
- 如果使用 8 字节的前缀,则计数器的大小应为 64 位而不是 128 位;这是一个设计特性,但如果为计数器保留的位数较小,则可能会导致溢出(不过当前设置为 64 位是可以的)
- 默认计数器初始值设置为 1,而 CTR 模式始终从 0 开始计数;这可能是计数器设计中的一个差一错误
言归正传:
from Crypto.Cipher import AES
from Crypto.Util import Counter
key = '7842f0a1ebc38f44e3e0c81943f68582'.decode('hex')
iv = 'd01f40dfc8ec8cd9'.decode('hex')
ctr_e = Counter.new(64, prefix=iv, initial_value=0)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr_e)
with open('output.pycrypto.mp4', 'wb') as fout:
with open('input.mp4', 'rb') as fin:
fout.write(encryptor.encrypt(fin.read()))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)