The below code snippet that AES-decrypts some bytes using Cryptodome works as I expect:
from Crypto.Cipher import AES
from Crypto.Util import Counter
key = b'\x12' * 32
decryptor = AES.new(key, AES.MODE_CTR,counter=Counter.new(nbits=128, little_endian=True))
print(decryptor.decrypt(b'Something encrypted'))
The below uses Python Cryptography, and gives different results:
from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms
key = b'\x12' * 32
decryptor = Cipher(algorithms.AES(key), modes.CTR(b'\0' * 16)).decryptor()
print(decryptor.update(b'Something encrypted'))
Why? And how can I change the Python Cryptography version to output the same results as Cryptodome?
(Context is writing AES decrypt code for unzipping files, and am considering using Python Cryptography)
In PyCryptodome the counter is started at 1 by default. Also, the counter for little endian counts as follows: 0x0100...0000, 0x0200...0000, 0x0300...0000
etc.
Since in Cryptography the endianess of the counter cannot be configured and big endian is used, this count cannot be implemented. Although the start value can be explicitly set to 0x0100...00
, but the counter would then count: 0x0100...0000, 0x0100...0001, 0x0100...0002
etc.
This can be verified with the following code:
from Crypto.Cipher import AES
from Crypto.Util import Counter
key = b'\x12' * 32
decryptor = AES.new(key, AES.MODE_CTR,counter=Counter.new(nbits=128, little_endian=True, initial_value=1))
print(decryptor.decrypt(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx').hex())
from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms
key = b'\x12' * 32
decryptor = Cipher(algorithms.AES(key), modes.CTR(b'\x01' + b'\0' * 15)).decryptor()
print(decryptor.update(b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx').hex())
with the output:
faebe2ab213094fcd5c9ec3dae32372b 13b3b971b7694faa5e15f5387ac5a67f bc5dbc82ce54cf1bbe2719488b322078
faebe2ab213094fcd5c9ec3dae32372b 6ddda72218780c287bc74956395bf7db 0603820b26889ec64e7f7964a14518c5
Because the counter value for the first block matches, the first block is identical. However, because of the different values for the following blocks the following blocks are different.
I currently don't see any way how the Cryptography library could be used to generate the PyCryptodome library result when PyCryptodome is configured for little endian.