The idea is to implement the Padding Oracle Attack against the Oracle implemented in the file oracle.py. So, we must implement an "attack" function that, given an encrypted message (as a byte-string), recovers the original cleartext message.
To download my repo:
git clone https://github.com/jjcomline/padding_oracle_attack
Now you just run the attack.py with the text you want (you can modify it in the test_the_attack() function) and see that is working. If you want you can erase the attack() function and implement it by yourself. This is what I've done and the main goal of this short script: learn how this attack works and implement it.
Your task is to implement an oracle-padding attack, as discussed during lecture and described in the included paper, against the given Oracle implemented by oracle.py.
You can freely study oracle.py, but your solution must import only three names from our module, namely:
- the function encrypt, which takes a byte-string and returns its encryption (using a random key and IV)
- the function is_padding_ok, which takes a byte-string an returns whether the decrypted message has a correct padding
- the constant BLOCK_SIZE, which corresponds to the block-size of the underlying encryption algorithm (AES128, in our case; however, your code should not depend on that).
To import these three names you can use: from oracle import encrypt, is_padding_ok, BLOCK_SIZE
Then, you must implement an "attack" function that, given an encrypted message (as a byte-string), recovers the original cleartext message. You can test your implementation of the attack by encrypting several byte-strings, say S, and comparing S with attack(encrypt(S)); for instance:
def test_the_attack(): messages = (b'Attack at dawn', b'', b'Giovanni', b"In symmetric cryptography, the padding oracle attack can be applied to the CBC mode of operation," + b"where the "oracle" (usually a server) leaks data about whether the padding of an encrypted " + b"message is correct or not. Such data can allow attackers to decrypt (and sometimes encrypt) " + b"messages through the oracle using the oracle's key, without knowing the encryption key") for msg in messages: print('Testing:', msg) cracked_ct = attack(encrypt(msg)) assert cracked_ct == msg
if name == 'main': test_the_attack()