5

I don't know why when I encrypt in AES a text with the PyCrypto (Crypto.Cipher- AES), the result isn't the same as the ciphertext generate by a code in C.

For example, the following code gives me

99756ed0115f676cef45ae25937bfd63247358a80803dde3fc1eae4953ee7277

instead of

CC613A0BDC930DABEA7A26126CE489EA

here is my code:

key = '1F61ECB5ED5D6BAF8D7A7068B28DCC8E'
IV = 16 * '\x00'
mode = AES.MODE_CBC
encryptor = AES.new(key, mode, IV=IV)
text = '020ABC00ABCDEFf8d500000123456789'
ciphertext = encryptor.encrypt(text)
print binascii.hexlify(ciphertext)
msw
  • 42,753
  • 9
  • 87
  • 112
TomasG
  • 53
  • 1
  • 1
  • 4
  • 1
    Please show how the text is being encrypted from C. – Uyghur Lives Matter Aug 22 '15 at 19:54
  • 1
    If you use the sample vectors from the FIPS-197 AES Standard do you get the correct result? http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf Note you may have to test with Electronic Code Book Mode (ECB) to make sure your mode does not change the outcome. Though ECB Mode should not be used in any end product – Brian Cain Aug 22 '15 at 19:55
  • AES is a block cipher meaning a short cleartext will be padded out to 128 bits or 256 bits before encrypting. The output you don't like is exactly 256 bits, which is a proper length; the output of your C program is 128 bits long. The two libraries have different default block sizes. This is independent of key length. – msw Aug 22 '15 at 20:04

1 Answers1

14

You need to unhexlify both the key and text (example in IPython using Python 3);

In [1]: from Crypto.Cipher import AES

In [2]: import binascii

In [3]: import os

In [4]: key = binascii.unhexlify('1F61ECB5ED5D6BAF8D7A7068B28DCC8E')

In [5]: IV = os.urandom(16)

In [6]: binascii.hexlify(IV).upper()
Out[6]: b'3C118E12E1677B8F21D4922BE4B2398E'

In [7]: encryptor = AES.new(key, AES.MODE_CBC, IV=IV)

In [8]: text = binascii.unhexlify('020ABC00ABCDEFf8d500000123456789')

In [9]: ciphertext = encryptor.encrypt(text)

In [10]: print(binascii.hexlify(ciphertext).upper())
b'2133D236609558353F7C501E6EBBB8D9

Edit: As André Caron correctly states in the comments, it is generally a bad idea to use an IV consisting of only zeroes. I've changed the code to use a random IV. Note that the IV should also be communicated to the receiver; it is needed for decryption. Often the IV is prepended to the ciphertext.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
  • Thanks Roland for your answer. You're right, I forgot to convert the hexadecimals values. – TomasG Aug 22 '15 at 21:51
  • I wouldn't recommend propagating use of a null initialization vector. Python has built-in support for cryptographic-safe generation of random bytes with [os.urandom()](https://docs.python.org/2/library/os.html#os.urandom). We should update the answer to use something like `IV = os.urandom(16)`. – André Caron Jan 24 '17 at 13:06
  • @AndréCaron A very good point. Updated to include a random IV. – Roland Smith Jan 24 '17 at 20:45