def test_challenge7(self): b64_encoded = read('7.txt') ciphertext = base64_to_bytes(b64_encoded) key = 'YELLOW SUBMARINE' plaintext = ecb_decrypt(ciphertext, key) # print plaintext self.assertIn('Play that funky music', plaintext)
def test_challenge10(self): ciphertext = base64_to_bytes(read('10.txt')) key = 'YELLOW SUBMARINE' iv = '\x00' * 16 plaintext = cbc_decrypt(ciphertext, key, iv) ciphertext = cbc_encrypt(plaintext, key, iv) plaintext2 = cbc_decrypt(ciphertext, key, iv) self.assertEquals(plaintext, plaintext2)
def test_challenge20(self): plaintexts = [ base64_to_bytes(line) for line in utils.readlines('20.txt') ] key = encryption_key() nonce = '\0' * 8 ciphertexts = [ ctr_encrypt(m, key, nonce) for m in plaintexts ] # Because of the fixed-nonce, the encrypted keystream bytes are # repeated for every plaintext message. # # ciphertext[i] ^ keystream[i] = plaintext[i] # # We can create a transposed ciphertext message by concatenating # ciphertext[i] from every encrypted message and then xor'ing that # against a guessed keystream byte. Then we can test whether the # resulting plaintext looks like english based on character # distributions. If so, then we've figured out the keystream byte. keystream = '' for index in itertools.count(): transposed = ''.join(m[index:index+1] for m in ciphertexts) if not transposed: break allowed_chars = None if index == 0: allowed_chars = string.ascii_uppercase + '"\'' score, _, key = crack.find_best_single_byte_key( transposed, allowed_chars=allowed_chars ) # print 'Best score for index {}: {}'.format(index, score) keystream += key[0] recovered_plaintexts = [ bitops.xor(m, keystream) for m in ciphertexts ] # for m in recovered_plaintexts: # print m self.assertIn( '\'Cause my girl is definitely mad / \'Cause it took us too long to do this album', recovered_plaintexts )
def test_challenge18(self): ciphertext = base64_to_bytes('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==') nonce = '\x00' * 8 plaintext = ctr_decrypt(ciphertext, 'YELLOW SUBMARINE', nonce) self.assertEqual( 'Yo, VIP Let\'s kick it Ice, Ice, baby Ice, Ice, baby ', plaintext ) plaintext = 'the quick brown fox jumped over the lazy dog.' key = encryption_key() ciphertext = ctr_encrypt(plaintext, key, nonce) self.assertEqual(plaintext, ctr_decrypt(ciphertext, key, nonce))
def test_challenge6(self): self.assertEquals( 37, hamming_distance('this is a test', 'wokka wokka!!!') ) b64_encoded = read('6.txt') ciphertext = base64_to_bytes(b64_encoded) distances = [block_distance(k, ciphertext) for k in range(2, 41)] distances.sort(key=lambda t: t[0]) dist, keysize = distances[0] # print 'dist: {}, key_size: {}'.format(dist, keysize) key = test_keysize(keysize, ciphertext) # print 'Testing key size: {}. Key: {}'.format(keysize, bytes_to_hex(key)) plaintext = repeating_key_xor(ciphertext, key) # print 'Decrypted:\n{}'.format(plaintext) self.assertIn( 'Play that funky music', plaintext )
def test_challenge25(self): ciphertext = convert.base64_to_bytes(utils.read('25.txt')) plaintext = crypto.ecb_decrypt(ciphertext, 'YELLOW SUBMARINE') key = crypto.encryption_key() nonce = '\x00' * 8 ciphertext = crypto.ctr_encrypt(plaintext, key, nonce) # The edit function lets us recover the original keystream because # in CTR mode: plaintext ^ keystream = ciphertext and then through # the magic of xor: # # plaintext ^ ciphertext = keystream # # Through the edit function, we know the plaintext and ciphertext # for every index in the byte stream. keystream = '' for offset in range(len(ciphertext)): new_ciphertext = edit(ciphertext, key, nonce, offset, 'A') keystream += bitops.xor(new_ciphertext[offset], 'A') recovered_plaintext = bitops.xor(ciphertext, keystream) self.assertEquals(plaintext, recovered_plaintext)
def ecb_oracle(plaintext, key='YELLOW SUBMARINE', prefix=''): secret = base64_to_bytes('Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK') full = prefix + plaintext + secret return ecb_encrypt(full, key)
import crack import bitops import itertools import utils import string from myrandom import MT19937 from collections import OrderedDict, Counter, defaultdict from convert import base64_to_bytes, bytes_to_hex from crypto import (cbc_decrypt, cbc_encrypt, encryption_key, iv, PaddingError, strip_pkcs_7, ctr_decrypt, ctr_encrypt, twister_encrypt, twister_decrypt, random_padding) import myrandom import random secret_messages = [ base64_to_bytes(c) for c in [ 'MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=', 'MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=', 'MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==', 'MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==', 'MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl', 'MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==', 'MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==', 'MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=', 'MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=', 'MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93', ] ] def encrypt_random_choice(key):
return ' ', curses.color_pair(1) else: return ch, 0 def _clamp(self, val, min, max): if val < min: return min elif val >= max: return max - 1 else: return val if __name__ == '__main__': plaintexts = [ base64_to_bytes(m) for m in [ 'SSBoYXZlIG1ldCB0aGVtIGF0IGNsb3NlIG9mIGRheQ==', 'Q29taW5nIHdpdGggdml2aWQgZmFjZXM=', 'RnJvbSBjb3VudGVyIG9yIGRlc2sgYW1vbmcgZ3JleQ==', 'RWlnaHRlZW50aC1jZW50dXJ5IGhvdXNlcy4=', 'SSBoYXZlIHBhc3NlZCB3aXRoIGEgbm9kIG9mIHRoZSBoZWFk', 'T3IgcG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==', 'T3IgaGF2ZSBsaW5nZXJlZCBhd2hpbGUgYW5kIHNhaWQ=', 'UG9saXRlIG1lYW5pbmdsZXNzIHdvcmRzLA==', 'QW5kIHRob3VnaHQgYmVmb3JlIEkgaGFkIGRvbmU=', 'T2YgYSBtb2NraW5nIHRhbGUgb3IgYSBnaWJl', 'VG8gcGxlYXNlIGEgY29tcGFuaW9u', 'QXJvdW5kIHRoZSBmaXJlIGF0IHRoZSBjbHViLA==', 'QmVpbmcgY2VydGFpbiB0aGF0IHRoZXkgYW5kIEk=', 'QnV0IGxpdmVkIHdoZXJlIG1vdGxleSBpcyB3b3JuOg==',
def test_base64_to_bytes_with_padding(self): self.assertEquals('M', convert.base64_to_bytes('TQ==')) self.assertEquals('Ma', convert.base64_to_bytes('TWE='))