This is an old revision of the document!
Before starting the labs, download openssl 1.1.0 from here. Save the file to some local folder accessible by you, then compile it and install it to some folder. Open the unpacked folder from bash, and run the following commands:
linux$ ./config --prefix=/home/student/local --openssldir=/home/student/local/openssl linux$ make linux$ make test linux$ make install
(in case of trouble, check also the instructions at the end of lab 8).
While the tools are building/compiling you may start working on some of the exercises.
In this exercise you will implement the Birthday attack on SHA-1. The goal is to obtain a collision in the first four bytes of the hash.
You can start from this code:
import hashlib import random N_MESSAGES = 2**16 # 2^16 random messages N_COLL_BYTES = 4 def generate_messages(): msgs = [] for i in xrange(N_MESSAGES): msgs.append("Ana are %d mere si %d pere" % (i, random.randint(0, 100000))) return msgs def find_collision(msgs): hashes = dict() # will keep first N_COLL_BYTES bytes of each hash # TODO - find collision and return it as a tuple (msg1, msg2) return None # return None if no collision is found def main(): while True: # Generate N_MESSAGES (2^16) different random messages msgs = generate_messages() # Find a hash collision collision = find_collision(msgs) # collision = (msg1, msg2) if collision: # print collision (the two messages and their hash) in a readable format print collision[0] # msg1 print hashlib.sha1(collision[0]).hexdigest() # msg1 hash print collision[1] # msg2 print hashlib.sha1(collision[1]).hexdigest() # msg2 hash break if __name__ == '__main__': main()
Can you also find a collision in the first 5 bytes of the hash?
hashlib.sha1(msg).hexdigest()
Generate a 1024 bit RSA key pair.
Write an oracle function that uses the private key to answer the question “is the plaintext of this message even or odd” (is the last bit of the message 0 or 1). Imagine for instance a server that accepted RSA-encrypted messages and checked the parity of their decryption to validate them, and spat out an error if they were of the wrong parity.
Anyways: function returning true or false based on whether the decrypted plaintext was even or odd, and nothing else.
Take the following string and un-Base64 it in your code (without looking at it!) and encrypt it to the public key, creating a ciphertext:
With your oracle function, you can trivially decrypt the message.
Here's why:
That means the plaintext is less than half the modulus.
You can repeatedly apply this heuristic, once per bit of the message, checking your oracle function each time.
Your decryption function starts with bounds for the plaintext of [0,n].
Each iteration of the decryption cuts the bounds in half; either the upper bound is reduced by half, or the lower bound is.
After log2(n) iterations, you have the decryption of the message.
Print the upper bound of the message as a string at each iteration; you'll see the message decrypt “hollywood style”.
Decrypt the string (after encrypting it to a hidden private key) above.
As we discussed in class, Diffie and Hellman proposed the first public key exchange mechanism such that two parties, that did not share any previous secret could establish a common secret. This allows the parties to have a shared key that only they know (except if there is an active man in the middle attack, which is usually solved by using TLS/certificates, but we shall not focus on that here).
Download the lab code from here. After unzipping, you'll find the source code for a client (dhe.c) and a server (dhe_server.c), along with a Makefile and fixed Diffie-Hellman p and g params in the files dhparam.pem.
The client and server have a similar structure. Each of them should build a public key, then send it to the other party, receive the public key from the other party and finally compute the secret key. Your task is to complete the missing parts. For this, consult the openssl documentation here. Since they are similar, focus only on one of them and then do similarly on the other one.
The makefile should help you build both. Just type 'make all'. After completing the necessary todo's in the file, you can start the server by typing 'make start_server' and the client with 'make start_client'.
If all goes well, you should see the same secret key on both client and server.