简体   繁体   English

由openssl和PyCrypto加密AES_128_CTR

[英]AES_128_CTR encryption by openssl and PyCrypto

Wondering the right way to convert a AES_128_CTR encryption by openssl to PyCrypto. 想知道通过openssl将AES_128_CTR加密转换为PyCrypto的正确方法。

First, I did an encryption by openssl as following: 首先,我通过openssl进行了加密,如下所示:

openssl enc -aes-128-ctr -in input.mp4 -out output.openssl.mp4 -K 7842f0a1ebc38f44e3e0c81943f68582 -iv d01f40dfc8ec8cd9

And then, I tried to do the same thing through PyCrypto: 然后,我尝试通过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()))

I assume they are supposed to be similar, but it is not: 我认为他们应该是相似的,但它不是:

diff output.openssl.mp4 output.pycrypto.mp4
Binary files output.openssl.mp4 and output.pycrypto.mp4 differ

OpenSSL behaves as expected (fortunately, as documentation to this fact is missing for the command line) and uses the given IV as leftmost bytes of a big endian counter. OpenSSL的行为符合预期(幸运的是,因为命令行缺少对此事实的记录)并且使用给定的IV作为大端计数器的最左边的字节。 In other words, the bytes given are the most significant part of the 16 byte counter. 换句话说,给出的字节是16字节计数器中最重要的部分。 The code in the question uses the IV as initial counter value, ie it is interpreted as the least significant part of the counter. 问题中的代码使用IV作为初始计数器值,即它被解释为计数器的最不重要部分。

Now it took me some time to fix the Python code as there are two problems with the Counter class I had to work around: 现在我花了一些时间来修复Python代码,因为我必须解决Counter类的两个问题:

  • the size of the counter should be 64 bit instead of 128 bit if a prefix of 8 bytes is used; 如果使用8字节的前缀,则计数器的大小应为64位而不是128位; this is a design feature, but it may cause overflow if the amount of bits reserved for the counter is small (it's OK with the current setting of 64 bit though) 这是一个设计特性,但是如果为计数器保留的位数很小,它可能会导致溢出(虽然当前设置为64位但是没有)
  • the default initial counter value is set to 1 while CTR mode always starts counting at 0; 默认初始计数器值设置为1,而CTR模式始终从0开始计数; this is likely an off-by-one bug in the Counter design 这可能是Counter设计中的一个错误

So without further ado: 所以不用多说:

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()))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM