Question

I'm comparing AES implementations in Python from the pycrypto and the cryptography.io library.

from cryptography.hazmat.primitives.ciphers import Cipher, modes, algorithms
from cryptography.hazmat.backends import default_backend  # http://cryptography.io
from Crypto.Cipher import AES  # http://pycrypto.org

key = b'Sixteen byte key'
iv = b'Sixteen byte ivv'
cipher1 = AES.new(key, AES.MODE_CFB, iv)
cipher2 = Cipher(algorithms.AES(key), modes.CFB(iv), default_backend())

plaintext = b"Plaintext"

print(cipher1.encrypt(plaintext))
print(cipher1.decrypt(plaintext))
print(cipher2.encryptor().update(plaintext))
print(cipher2.decryptor().update(plaintext))

The MWE prints:

b'\xe4\xb4\xeb\xe3Si\x9ap\xee'
b'7\xda\x98\xee\x05\xe4\xa0\xc7,'
b'\xe4"\xd4mo\xa3;\xa9\xe0'
b'\xe4"\xd4mo\xa3;\xa9\xe0'

Why are the outputs different?

Was it helpful?

Solution

The answer appears to be that PyCrypto implements CFB-8 by default, which is a variant on normal CFB. https://github.com/digitalbazaar/forge/issues/100 describes the issue in more detail.

OTHER TIPS

Based on Alex Gaynor's answer, here is a more detailed description:

According to the standard, the input size must be a multiple of the segment size. Most implementations use 16 byte (128 bit) segment size by default, and ignore this requirement. PyCrypto uses 8 byte segments by default, but you can change it like so:

cipher1 = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

This produces identical encrypted data with the other library.

Kindly use cryptography mode as "CFB8". The pycrypto and cryptography output will match. for ex.cipher2 = Cipher(algorithms.AES(key), modes.CFB8(iv), default_backend())

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top