Created
October 18, 2017 18:58
-
-
Save singe/e680fef88b61b2ae4aac3ff051306695 to your computer and use it in GitHub Desktop.
Simple demonstration of how you can recover plaintext from a stream cipher when the nonce is reused.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from Cryptodome.Cipher import AES | |
from Cryptodome.Random import get_random_bytes | |
pairwiseTransientKey = b'pairwiseTransKey' | |
EAPOLheader = b'Unencrypted Frame Stuff' | |
plaintext1 = b'Attack at dawn' | |
nonce1 = get_random_bytes(11) | |
cipher1 = AES.new(pairwiseTransientKey, AES.MODE_CCM, nonce1) | |
cipher1.update(EAPOLheader) | |
msg1 = nonce1, EAPOLheader, cipher1.encrypt(plaintext1), cipher1.digest() | |
plaintext2 = b'Run for the hills' | |
#nonce2 = get_random_bytes(11) | |
nonce2 = nonce1 #The nonce aka IV aka (packet number || MAC) is repeated | |
cipher2 = AES.new(pairwiseTransientKey, AES.MODE_CCM, nonce2) | |
cipher2.update(EAPOLheader) | |
msg2 = nonce2, EAPOLheader, cipher2.encrypt(plaintext2), cipher2.digest() | |
pairwiseTransientKeystream = bytes(a ^ b for a, b in zip(msg1[2], plaintext1)) | |
decrypted = bytes(a ^ b for a, b in zip(msg2[2], pairwiseTransientKeystream)) | |
if decrypted == plaintext2[0:len(decrypted)]: | |
print (f'Plaintext 1: {plaintext1}') | |
print (f'Plaintext 2: {plaintext2}') | |
print (f'Recovered plaintext 2: {decrypted}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output:
▶ ./aes-ccm-test.py
Plaintext 1: b'Attack at dawn'
Plaintext 2: b'Run for the hills'
Recovered plaintext 2: b'Run for the hi'