AES_128_CTR encryption by openssl and PyCrypto

2024/11/15 18:02:11

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
Answer

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 Counterkey = '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://en.xdnf.cn/q/71763.html

Related Q&A

How can i determine the exact size of a type used by python

>>> sys.getsizeof(int) 436 #? does this mean int occupies 436 bytes .>>> sys.getsizeof(1) 12 #12 bytes for int object, is this the memory requirement.I thought int in python is repre…

Python list.clear complexity [duplicate]

This question already has answers here:Python list.clear() time and space complexity?(4 answers)Closed 2 years ago.What is the complexity of the Python 3 method list.clear() ?It is not given here: ht…

Unresolved import org.python / working with jython and java?

Im using Eclipse and I"m trying to create a java program that can run my python code. Im following the guidelines on this page: http://jythonpodcast.hostjava.net/jythonbook/en/1.0/JythonAndJavaInt…

elegant unpacking variable-length tuples

A real, if silly problem:https://github.com/joshmarshall/tornadorpc/blob/master/tornadorpc/base.pydef start_server(handlers, ...):...for (route, handler) in handlers:...Normally "handlers" is…

Extracting data from a 3D scatter plot in matplotlib

Im writing an interface for making 3D scatter plots in matplotlib, and Id like to access the data from a python script. For a 2D scatter plot, I know the process would be:import numpy as np from matpl…

How does Pythonic garbage collection with numpy array appends and deletes?

I am trying to adapt the underlying structure of plotting code (matplotlib) that is updated on a timer to go from using Python lists for the plot data to using numpy arrays. I want to be able to lower …

What is the default if I install virtualenv using pip and pip3 respectively?

I used sudo pip install virtualenv, then when I run virtualenv ENV in a directory, I get a Python 2 virtual enviroment.If I use pip3 install virtualenv to install virtualenv again, will it override the…

Flask Admin ModelView different fields between CREATE and EDIT

In a Flask app using Flask Admin I would like to be able to define different form fields in the Edit section of a ModelView than those in the Create section.The form_columns setting applies to both Cre…

Python compilation error: LONG_BIT definition appears wrong for platform

This error message is not unknown, I have already reinstalled many packages, but so far not yet found a solution.I get the following error from the command pip install cryptography/usr/include/python2.…

Randomly sampling lines from a file

I have a csv file which is ~40gb and 1800000 lines. I want to randomly sample 10,000 lines and print them to a new file.Right now, my approach is to use sed as:(sed -n $vars < input.txt) > output…