def smallDHDemo(): # Set "p" to 37 and "g" to 5. This algorithm is so easy I'm not even # going to explain it. Just do what I do. p = 37; g = 5; # Generate "a", a random number mod 37. Now generate "A", which is "g" # raised to the "a" power mode 37 --- A = (g**a) % p. a = getOneRandomByte() % p; A = pow(g, a, p) # Do the same for "b" and "B". b = getOneRandomByte() % p B = pow(g, b, p) # "A" and "B" are public keys. Generate a session key with them; set # "s" to "B" raised to the "a" power mod 37 --- s = (B**a) % p. s_b = pow(B, a, p) # Do the same with A**b, check that you come up with the same "s". s_a = pow(A, b, p) # print print(s_a,s_b) assert(s_a == s_b) # To turn "s" into a key, you can just hash it to create 128 bits of # key material (or SHA256 it to create a key for encrypting and a key # for a MAC). encKey, macKey = secretToKeys(intToBytes(s_a))
def smallDHDemo(): # Set "p" to 37 and "g" to 5. This algorithm is so easy I'm not even # going to explain it. Just do what I do. p = 37 g = 5 # Generate "a", a random number mod 37. Now generate "A", which is "g" # raised to the "a" power mode 37 --- A = (g**a) % p. a = getOneRandomByte() % p A = pow(g, a, p) # Do the same for "b" and "B". b = getOneRandomByte() % p B = pow(g, b, p) # "A" and "B" are public keys. Generate a session key with them; set # "s" to "B" raised to the "a" power mod 37 --- s = (B**a) % p. s_b = pow(B, a, p) # Do the same with A**b, check that you come up with the same "s". s_a = pow(A, b, p) # print print(s_a, s_b) assert (s_a == s_b) # To turn "s" into a key, you can just hash it to create 128 bits of # key material (or SHA256 it to create a key for encrypting and a key # for a MAC). encKey, macKey = secretToKeys(intToBytes(s_a))
def doMTEncrypt(): prefixLen = getOneRandomByte() seed = getOneRandomByte() * 256 + getOneRandomByte() prefix = b'' letters = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' for i in range(prefixLen): prefix += choice(letters).to_bytes(1, byteorder='big') rawInput = prefix + b'AAAAAAAAAAAAAA' return MTStreamCipher(seed, rawInput)
def doMTEncrypt(): prefixLen = getOneRandomByte(); seed = getOneRandomByte() * 256 + getOneRandomByte(); prefix = b''; letters = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' for i in range(prefixLen): prefix += choice(letters).to_bytes(1, byteorder='big'); rawInput = prefix + b'AAAAAAAAAAAAAA'; return MTStreamCipher(seed, rawInput)
# Written against python 3.3.1 # Matasano Problem 14 # Byte-at-a-time ECB decryption, Partial control version from prob11 import getOneRandomByte from prob1 import base64toRaw from prob12 import constant_ecb_encrypt, padStr from prob8 import chunks from ssl import RAND_bytes # Take your oracle function from #12. # Now generate a random count of random bytes and # prepend this string to every plaintext. You are now doing: # AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key) prefixValue = RAND_bytes(getOneRandomByte()) # += bytes(chr(getOneRandomByte()), 'UTF-8'); def prob14Encrypt(rawInput): unknownB64 = b'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg' + \ b'aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq' + \ b'dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg' + \ b'YnkK' unknownRaw = base64toRaw(unknownB64) return constant_ecb_encrypt(prefixValue + rawInput + unknownRaw) # Same goal: decrypt the target-bytes. def recoverBytes(): # first, determine number of bytes needed to push prefix up to a block boundry
def encryptString(): myString = rawStrings[getOneRandomByte() % len(rawStrings)]; iv = generateAESKey(); # it's a 16-byte value... myOut = aes_cbc_enc(addPKCS7Padding(myString, 16), aeskey, iv); return myOut, iv;
# Written against python 3.3.1 # Matasano Problem 14 # Byte-at-a-time ECB decryption, Partial control version from prob11 import getOneRandomByte from prob1 import base64toRaw from prob12 import constant_ecb_encrypt, padStr from prob8 import chunks from ssl import RAND_bytes # Take your oracle function from #12. # Now generate a random count of random bytes and # prepend this string to every plaintext. You are now doing: # AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key) prefixValue = RAND_bytes(getOneRandomByte());# += bytes(chr(getOneRandomByte()), 'UTF-8'); def prob14Encrypt(rawInput): unknownB64 = b'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg' + \ b'aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq' + \ b'dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg' + \ b'YnkK' unknownRaw = base64toRaw(unknownB64); return constant_ecb_encrypt(prefixValue + rawInput + unknownRaw); # Same goal: decrypt the target-bytes. def recoverBytes(): # first, determine number of bytes needed to push prefix up to a block boundry # and where the first block fully controlled by my input lies (effectively, determine prefix length) numBytesForPrefix, firstControlledBlock = determinePrefixLength(); # deterine target plaintext length targetPlaintextLength = prob14DeterminePlaintextLength() + (numBytesForPrefix) - (firstControlledBlock * 16);