def main(): key = random_bytes(16) nonce = 0 with open("inpChall20.txt") as f: secrets = f.readlines() secrets = [b64decode(secret) for secret in secrets] expected = secrets secrets = [ctr_encrypt(key, nonce, secret) for secret in secrets] min_length = min(len(secret) for secret in secrets) truncated = [secret[:min_length] for secret in secrets] concatenated = b"".join(truncated) keys = rank_xor_repeating_keys(concatenated, min_length) # found through analysis key_indices = { 0: 3, } key = bytes([keys[i][key_indices.get(i, 0)] for i in range(len(keys))]) plaintexts = [xor_bytes(secret, key) for secret in secrets] for i in range(len(expected)): print(plaintexts[i]) assert (expected[i].startswith(plaintexts[i]))
#!/usr/bin/python3 import aes # These CTR test vectors are from NIST special publication 800-38a # CTR-AES128: Encryption ctx = aes.build_encryption_context( bytes.fromhex('2b7e151628aed2a6abf7158809cf4f3c')) counter = bytes.fromhex('f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff') # Block #1 data = bytes.fromhex('6bc1bee22e409f96e93d7e117393172a') aes.ctr_encrypt(data, counter, ctx) assert data == bytes.fromhex('874d6191b620e3261bef6864990db6ce') assert counter == bytes.fromhex('f0f1f2f3f4f5f6f7f8f9fafbfcfdff00') # Block #2 data = bytes.fromhex('ae2d8a571e03ac9c9eb76fac45af8e51') aes.ctr_encrypt(data, counter, ctx) assert data == bytes.fromhex('9806f66b7970fdff8617187bb9fffdff') assert counter == bytes.fromhex('f0f1f2f3f4f5f6f7f8f9fafbfcfdff01') # Block #3 data = bytes.fromhex('30c81c46a35ce411e5fbc1191a0a52ef') aes.ctr_encrypt(data, counter, ctx) assert data == bytes.fromhex('5ae4df3edbd5d35e5b4f09020db03eab')
def get_token(userdata): global token_prefix prefix = token_prefix suffix = ";comment2=%20like%20a%20pound%20of%20bacon" cookie = prefix + escape(userdata) + suffix return ctr_encrypt(KEY, NONCE, cookie.encode('latin-1'))
def edit(ciphertext, key, offset, newtext): key, nonce = key plaintext = ctr_decrypt(key, nonce, ciphertext) plaintext = plaintext[:offset] + newtext + plaintext[offset + len(newtext):] return ctr_encrypt(key, nonce, plaintext)
from aes import ctr_encrypt, ctr_decrypt from xor import xor_bytes def edit(ciphertext, key, offset, newtext): key, nonce = key plaintext = ctr_decrypt(key, nonce, ciphertext) plaintext = plaintext[:offset] + newtext + plaintext[offset + len(newtext):] return ctr_encrypt(key, nonce, plaintext) with open("25.txt") as f: # not sure what we mean by the recovered plaintext from the ECB exercice, # but let's assume that this is our plaintext... secret = b64decode(f.read()) key = urandom(16) nonce = int.from_bytes(urandom(8), byteorder='big') ciphertext = ctr_encrypt(key, nonce, secret) # could do block per block, but let's do it all at once... edited = edit(ciphertext, (key, nonce), 0, bytes([0] * len(ciphertext))) # 0 ^ keystream gives us our keystream! keystream = edited plaintext = xor_bytes(keystream, ciphertext) assert (plaintext == secret)
QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc= VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs= SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0 SW4gdGhlIGNhc3VhbCBjb21lZHk7 SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw= VHJhbnNmb3JtZWQgdXR0ZXJseTo= QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=""".split() secrets = [b64decode(secret) for secret in secrets] expected = secrets key = urandom(16) nonce = 0 secrets = [ctr_encrypt(key, nonce, secret) for secret in secrets] # After sorting the key bytes by their best picks, what index should we pick? # By default, 0. If there's a value in this map, it was found through analysis # of the plaintexts. key_bytes_index = { 0: 1, 30: 1, 33: 4, 34: 7, 35: 11, 36: 9, 37: 212, } keystream = bytearray()
from base64 import b64decode from os import urandom from aes import ctr_encrypt from xor import xor_bytes, rank_xor_repeating_keys key = urandom(16) nonce = 0 with open("20.txt") as f: secrets = f.readlines() secrets = [b64decode(secret) for secret in secrets] expected = secrets secrets = [ctr_encrypt(key, nonce, secret) for secret in secrets] min_length = min(len(secret) for secret in secrets) truncated = [secret[:min_length] for secret in secrets] concatenated = b"".join(truncated) keys = rank_xor_repeating_keys(concatenated, min_length) # found through analysis key_indices = { 0: 3, } key = bytes([keys[i][key_indices.get(i, 0)] for i in range(len(keys))]) plaintexts = [xor_bytes(secret, key) for secret in secrets]
def main(): secrets = """SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ== Q29taW5nIHdpdGggdml2aWQgZmFjZXM= RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ== RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4= SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA== T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ= UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA== QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU= T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl VG8gcGxlYXNlIGEgY29tcGFuaW9u QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA== QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk= QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg== QWxsIGNoYW5nZWQsIGNoYW5nZWQgdXR0ZXJseTo= QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4= VGhhdCB3b21hbidzIGRheXMgd2VyZSBzcGVudA== SW4gaWdub3JhbnQgZ29vZCB3aWxsLA== SGVyIG5pZ2h0cyBpbiBhcmd1bWVudA== VW50aWwgaGVyIHZvaWNlIGdyZXcgc2hyaWxsLg== V2hhdCB2b2ljZSBtb3JlIHN3ZWV0IHRoYW4gaGVycw== V2hlbiB5b3VuZyBhbmQgYmVhdXRpZnVsLA== U2hlIHJvZGUgdG8gaGFycmllcnM/ VGhpcyBtYW4gaGFkIGtlcHQgYSBzY2hvb2w= QW5kIHJvZGUgb3VyIHdpbmdlZCBob3JzZS4= VGhpcyBvdGhlciBoaXMgaGVscGVyIGFuZCBmcmllbmQ= V2FzIGNvbWluZyBpbnRvIGhpcyBmb3JjZTs= SGUgbWlnaHQgaGF2ZSB3b24gZmFtZSBpbiB0aGUgZW5kLA== U28gc2Vuc2l0aXZlIGhpcyBuYXR1cmUgc2VlbWVkLA== U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4= VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA== QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc= VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs= SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0 SW4gdGhlIGNhc3VhbCBjb21lZHk7 SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw= VHJhbnNmb3JtZWQgdXR0ZXJseTo= QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=""".split() secrets = [b64decode(secret) for secret in secrets] expected = secrets key = random_bytes(16) nonce = 0 secrets = [ctr_encrypt(key, nonce, secret) for secret in secrets] key_bytes_index = { 0: 1, 30: 1, 33: 4, 34: 7, 35: 11, 36: 9, 37: 212, } keystream = bytearray() while max(len(s) for s in secrets) > len(keystream): index = len(keystream) chars = [s[index] for s in secrets if len(s) > index] keys = rank_xor_char_keys(chars) key_byte_index = key_bytes_index.get(index, 0) key_byte = keys[key_byte_index] keystream.append(key_byte) plaintexts = [xor_bytes(secret, keystream) for secret in secrets] assert(len(plaintexts) == len(expected)) for i in range(len(expected)): print(plaintexts[i].decode()) assert(plaintexts[i] == expected[i]) assert(plaintexts == expected)