AES_128_CTR encryption by openssl and PyCrypto

你。 提交于 2019-12-07 08:20:30

问题


Wondering the right way to convert a AES_128_CTR encryption by openssl to PyCrypto.

First, I did an encryption by openssl as following:

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:

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

回答1:


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. In other words, the bytes given are the most significant part of the 16 byte counter. The code in the question uses the IV as initial counter value, i.e. it is interpreted as the least significant part of the counter.

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:

  • the size of the counter should be 64 bit instead of 128 bit if a prefix of 8 bytes is used; 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)
  • the default initial counter value is set to 1 while CTR mode always starts counting at 0; this is likely an off-by-one bug in the Counter design

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


来源:https://stackoverflow.com/questions/26835539/aes-128-ctr-encryption-by-openssl-and-pycrypto

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!