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
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:
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()))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With