Reputation: 15
I want to encrypt some data using AES in Python such that two encryptions of the same data give the same output (using the same key in both encryptions). I tried to use a static IV but I still get two different outputs given one input.
Here is what I did:
from Crypto.Cipher import AES
iv = 16 * '\x00'
cipher = AES.new(key, AES.MODE_CBC, iv)
I would like to obtain the same cipher if I decide to encrypt the same data multiple times. Do you know how to prevent the use of a salt? Thank you!
Upvotes: 0
Views: 3722
Reputation: 33203
The cipher
object here is the state and is initialized using the provided key data and initialization vector. Once you start to use this initialized keystate it is modified for each block you encrypt when you use CBC mode. That is the cipher block chaining in action. To have two separate encryptions you need to use two separate keystates. Or, as mentioned, you can use a mode (ECB) that does not affect the keystate when encrypting a block.
A demo (python3):
from Crypto.Cipher import AES
key = 16 * b'\0'
iv = 16 * b'\0'
plaintext = 16 * b'\x41'
a = AES.new(key, AES.MODE_CBC, iv)
b = AES.new(key, AES.MODE_CBC, iv)
ar = a.encrypt(plaintext)
br = b.encrypt(plaintext)
>>> ar
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> br
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
The disadvantage of ECB mode is everytime we encrypt this plaintext with this key and iv we will get this result. With CBC mode, each time we encrypt another block the keystate is changed and we get a different output which is dependent upon what has been encrypted before.
ECB Mode
>>> ecb = AES.new(16 * b'\0', AES.MODE_ECB)
>>> ecb.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> ecb.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
Each encryption produces the same result. No iv required.
CBC Mode
>>> cbc = AES.new(16 * b'\0', AES.MODE_CBC, 16 * b'\0')
>>> cbc.encrypt(16 * b'\x41')
b'\xb4\x9c\xbf\x19\xd3W\xe6\xe1\xf6\x84\\0\xfd[c\xe3'
>>> cbc.encrypt(16 * b'\x41')
b'o\x9fv\x9a\x9c\xaa\x03\x13\xba\x17\x8c\x1c.\x0f`v'
>>> cbc.encrypt(16 * b'\x41')
b'\n1\x165\xb5?\x04h\xa8\r>k\xdbK\xbc4'
The first block encrypts the same as ECB mode but subsequent blocks are different.
Futher discussion about modes of operation for block ciphers can be found online.
Upvotes: 2