-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchallenge25.py
45 lines (39 loc) · 1.6 KB
/
challenge25.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env python3
# Break "random access read/write" AES CTR
from utils import read
from aes import (
random_bytes_gen,
aes_ctr_encrypt,
aes_ctr_decrypt
)
from string import printable
KEY = random_bytes_gen(16)
NONCE = random_bytes_gen(8)
# --------------------------------------------------------
# ---------------------- functions -----------------------
# --------------------------------------------------------
def edit_ctr(ciphertext: bytes, offset: int, newtext: bytes, key: bytes = KEY, nonce: bytes = NONCE) -> bytes:
plaintext = aes_ctr_decrypt(ciphertext, key, nonce)
plaintext = plaintext[:offset] + newtext + plaintext[offset+len(newtext):]
return aes_ctr_encrypt(plaintext, key, nonce)
def recover_ctr_plaintext(ciphertext: bytes) -> bytes:
plaintext = b""
for index in range(len(ciphertext)):
for c in printable.encode():
# makes the code much faster to not send entire ct to edit
cipher_chunk = ciphertext[:index+1]
new_cipher = edit_ctr(cipher_chunk, index, bytes([c]))
if new_cipher[index] == cipher_chunk[index]:
plaintext += bytes([c])
print(plaintext)
return plaintext
# --------------------------------------------------------
# ------------------------- main -------------------------
# --------------------------------------------------------
def main():
plaintext = read('challenge25-text.txt').encode()
ciphertext = aes_ctr_encrypt(plaintext, KEY, NONCE)
recovered_pt = recover_ctr_plaintext(ciphertext)
print(recovered_pt)
if __name__ == "__main__":
main()