Skip to content

Instantly share code, notes, and snippets.

@belkka
Created July 2, 2024 17:22
Show Gist options
  • Save belkka/87fa85136349fa9af495974de53fb3ba to your computer and use it in GitHub Desktop.
Save belkka/87fa85136349fa9af495974de53fb3ba to your computer and use it in GitHub Desktop.
AES CBC padding oracle in Python 3
import os
from Crypto.Cipher import AES
class PaddingOracle:
def __init__(self, key: bytes):
assert len(key) in AES.key_size
self.k = key
def encrypt(self, pt: bytes) -> bytes:
iv = os.urandom(AES.block_size)
cipher = AES.new(self.k, AES.MODE_CBC, iv)
pad = AES.block_size - len(pt) % AES.block_size
return iv + cipher.encrypt(pt + pad.to_bytes() * pad)
def has_valid_padding(self, ct: bytes) -> bool:
cipher = AES.new(self.k, AES.MODE_CBC)
padded_pt = cipher.decrypt(ct)
pad = padded_pt[-1]
return padded_pt.endswith(pad.to_bytes() * pad)
@belkka
Copy link
Author

belkka commented Jul 2, 2024

padding is PKCS#7 [datatracker.ietf.org], i.e. one of

1
2 2
3 3 3
4 4 4 4
...
16 16 16 16 16 ... 16

Crypto.Cipher module provided by PyCryptodome

Hex-encoded key to initialize padding oracle (use bytes.from_hex(): d2ecd8e525321b2f282399662257ed6e
Hex-encoded messages to break using the padding oracle (do not decrypt them directly!):

  • 4ab43f57b05f2e735a691a3a9df542a89ba8af9c0cb95e93dab6bff923ddb8f0b0b22e1c09bb754d71d6c5469cb46d7d5755083348b1a7e98cf6ae9c9b061cbd642008982d56f67f54dc105cd180921f5b27b50df20b41c685f666a08947bef7
  • 0a843aefadae9ece328108d5fc667286f9bc30c954e70681776303e085155fd47e0d3070f5fcf4af0c91f2483bdecc3f
  • eab4cba2fcd67609fbb60b3a3cf4a2e26d333f6c0c7cf651011df8e5376cc0dca14937af61260c48824edb98a7795da3d032b22edb7e5a1ca219ea4b25e200c4d827817e1ecc999e2d1ea51eb2df48d696fa6940862c7dc1041e41d2c60e8ab8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment