Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sasc:laboratoare:10 [2016/05/24 11:26]
sergiu.costea
sasc:laboratoare:10 [2017/05/08 11:50] (current)
dan.dragan
Line 1: Line 1:
-===== Lab 10 - OpenSSL AEAD =====+===== Lab 10 - Public key encryption ​=====
  
-Before you start solving the exercises below, download the {{:​sasc:​laboratoare:​sasc_lab10.tar.gz|lab archive from here}}.+In this lab we'll do some cool exercises using public key encryption methods for key exchange and data encryption.
  
-==== Exercise ​0 - Feedback ====+Before starting the labs, download openssl 1.1.from [[https://​www.openssl.org/​source/​openssl-1.1.0c.tar.gz|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: 
 +<code bash> 
 +linux$ ./config --prefix=/​home/​student/​local --openssldir=/​home/​student/​local/​openssl 
 +linux$ make 
 +linux$ make test 
 +linux$ make install 
 +</​code>​ 
 +(in case of trouble, check also the instructions at the end of [[https://​ocw.cs.pub.ro/​courses/​sasc/​laboratoare/​08|lab 8]]).
  
-We invite ​you to assess the activity ​of the SASC team. Please share with us what you liked and disliked about this course, and if you have any extra suggestions,​ please let us know. SASC is a new course, and your feedback is very important for us as we continue to improve the course in the years ahead.+While the tools are building/​compiling ​you may start working on some of the exercises.
  
-You may find the feedback form [[http://​cs.curs.pub.ro/​2015/​course/​view.php?​id=204| here]]. 
  
 +==== Exercise 1: Diffie-Hellman key exchange (4p) ====
  
 +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).
  
-==== Exercise 1 ====+Download the lab code from {{:​ic:​laboratoare:​lab_dhe.zip|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 archive contains ​the source code for Exercise 2, but sadly it is encrypted. Luckily, we forgot ​to remove the password file from the archive.+<​note>​ 
 +Update ​the Makefile with the paths relevant ​to your installation folders 
 +</​note>​
  
-Use ''​openssl''​ commands ​to decrypt ​the source file.+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 [[https://​www.openssl.org/​docs/​man1.1.0/​crypto/​|here]]. Since they are similar, focus only on one of them and then do similarly on the other one.
  
-<note hint+The makefile should help you build both. Just type 'make all'​. 
-The file is encrypted ​using AES-256 in CBC mode.+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. 
 + 
 +<hidden
 +The solution ​is {{:​ic:​laboratoare:​lab_dhe_solved.zip|here}}. 
 +</​hidden>​ 
 + 
 + 
 +=== Bonus 1 === 
 + 
 +Perform the DH key exchange between two teams, sending the public key values over the network and verify that you get the same secret key. 
 + 
 +=== Bonus 2 === 
 + 
 +Use the secret key to encrypt some data (see previous labs) and check that the other party can decrypt it. 
 + 
 +==== Exercise 2: RSA parity oracle (4p) ==== 
 + 
 +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:​ 
 +<​note>​ 
 +VGhhdCdzIHdoeSBJIGZvdW5kIHlvdSBkb24ndCBwbGF5IGFyb3VuZCB3aXRoIHRoZSBGdW5reSBDb2xkIE1lZGluYQ==
 </​note>​ </​note>​
  
 + With your oracle function, you can trivially decrypt the message.
  
-==== Exercise ​====+Here's why: 
 +  * RSA ciphertexts are just numbers. You can do trivial math on them. You can for instance multiply a ciphertext by the RSA-encryption of another number; the corresponding plaintext will be the product of those two numbers. 
 +  * If you double a ciphertext (multiply it by (2**e)%n), the resulting plaintext will (obviously) be either even or odd. 
 +  * If the plaintext after doubling is even, doubling the plaintext didn't wrap the modulus --- the modulus is a prime number.
  
-In this exercise we'll use OpenSSL to encrypt and decrypt with AES-128-GCM. Unfortunately,​ AES-GCM ​is not supported by the command line utilities of OpenSSL so we'll have to implement it ourselves.+That means the plaintext ​is less than half the modulus.
  
-Open the file you decrypted in the previous exercise and inspect the code. There are two functions that need to be implemented:​ ''​aes_gcm_encrypt''​ and ''​aes_gcm_decrypt''​. We have included hints to guide you through the code.+You can repeatedly apply this heuristic, once per bit of the message, checking your oracle function each time.
  
-The main program initializes a dummy key and a dummy IV; a long message is then encrypted and decrypted. The encryption should automatically include the authentication tag at the end, and the decryption ​should return an error if the verification ​of the tag fails.+Your decryption ​function starts with bounds for the plaintext ​of [0,n].
  
-If you do not change keys and the implementation ​is ok, the ciphertext you obtain should be equal to our own. Otherwise, some of the tests will fail.+Each iteration of the decryption cuts the bounds in half; either the upper bound is reduced by halfor 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"​.
  
-Below we have included an example of encryption with RC2 (taken from the OpenSSL man pages). The AES-GCM encryption implementation is quite similar - the authentication tag is automatically appended when finalizing the encryption context.+Decrypt the string ​(after encrypting it to a hidden private keyabove.
  
-<code C> +{{:​ic:​laboratoare:parity_oracle.zip}}
-int do_crypt(FILE *in, FILE *out, int do_encrypt) ​{ +
-    /* Allow enough space in output buffer for additional block */ +
-    inbuf[1024],​ outbuf[1024 + EVP_MAX_BLOCK_LENGTH];​ +
-    int inlen, outlen; +
-    /* Bogus key and IVwe'd normally set these from +
-     * another source. +
-     */ +
-    unsigned char key[] = "​0123456789";​ +
-    unsigned char iv[] = "​12345678";​ +
-    /* Don't set key or IV because we will modify the parameters */ +
-    EVP_CIPHER_CTX_init(&​ctx);​ +
-    EVP_CipherInit_ex(&​ctx,​ EVP_rc2(), NULL, NULL, NULL, do_encrypt);​ +
-    EVP_CIPHER_CTX_set_key_length(&​ctx,​ 10); +
-    /* We finished modifying parameters so now we can set key and IV */ +
-    EVP_CipherInit_ex(&​ctx,​ NULL, NULL, key, iv, do_encrypt);​+
  
-    for(;;+==== Exercise 3: Merkle'​s puzzles ​(4p) ==== 
-        inlen fread(inbuf1, 1024in); + 
-        if(inlen <= 0) break; +Alice wants to share a secret with Bobbut she knows that if she explicitly tells it to BobEve somehow will find out (she hears everything). So she and Bob establish a small game which helps them think about the same secret, without saying it. The game goes like this: 
-        if(!EVP_CipherUpdate(&ctxoutbuf&outleninbufinlen)) { +  * Alice sends to Bot a list of puzzles. A puzzle looks like this: 
-            /* Error */ + 
-            ​EVP_CIPHER_CTX_cleanup(&ctx); +$\mathsf{Puzzle}_i = \mathsf{AES}(\mathsf{key} ​= 0^{14} \| i, \mathsf{plaintext = Puzzle} \| i \| secret_i)$ 
-            return ​0; +where $secret_i$ represents the $i$-th secret Alice generated ​(represents 8 randomly generated bytes) and which should be figured out by Bob. 
-        } +  * Bob receives the puzzles and randomly chooses one. He knows the first 14 bytes of the key are 0, so he tries to brute-force the rest of the key until he finds a plain text starting with "​Puzzle"​. This way, he knows Alice'​s secret ​(the last part of the plain text). 
-        ​fwrite(outbuf1outlen, out); +  * Bob sends the index of the puzzle that he solvedin order to let Alice know which secret they agreed on. 
-    ​} +In the endboth Alice and Bob share the same secretand Eve has no clue about it. 
-    ​if(!EVP_CipherFinal_ex(&ctxoutbuf, &outlen)) { + 
-        /* Error */ +Your job is to implement this mechanism starting from the following skeleton: 
-        ​EVP_CIPHER_CTX_cleanup(&ctx); +<file python merkle.py>​ 
-        return ​0; +import random 
-    } +import string 
-    ​fwrite(outbuf, 1outlen, out); +from Crypto.Cipher import AES 
-    ​EVP_CIPHER_CTX_cleanup(&ctx); +import os 
-    ​return 1; +   
-+def aes_enc(km)
-</code>+  """​ 
 +  Encrypt a message m with a key k in ECB mode using AES as follows: 
 +  c = AES(k, m
 + 
 +  ​Args:​ 
 +    m should be a bytestring multiple of 16 bytes (i.e. a sequence of characters such as '​Hello...'​ or '​\x02\x04...'​
 +    k should be a bytestring of length exactly 16 bytes. 
 + 
 +  Return: 
 +    The bytestring ciphertext c 
 +  """​ 
 +  aes = AES.new(k) 
 +  c = aes.encrypt(m) 
 + 
 +  ​return ​c 
 + 
 +def aes_dec(kc): 
 +  """​ 
 +  Decrypt a ciphertext c with a key k in ECB mode using AES as follows: 
 +  m = AES(kc) 
 + 
 +  Args: 
 +    ​c should be a bytestring multiple of 16 bytes (i.e. a sequence of characters such as '​Hello...'​ or '​\x02\x04...'​) 
 +    ​k should be a bytestring of length exactly 16 bytes. 
 + 
 +  Return: 
 +    The bytestring message m 
 +  """​ 
 +  aes = AES.new(k) 
 +  m = aes.decrypt(c) 
 + 
 +  return m 
 + 
 +alice_keys = [] 
 +bob_key = [] 
 + 
 +# TODO This is Alice. She generates 2^16 random keys and 2^16 puzzles. 
 +# A puzzle has the following formula: 
 +# puzzle[i] = aes_enc(key = 0..0 + iplaintext ="​Puzzle"​ + chr(i+ chr(j) + alice_keys[i]
 +# This function shall fill in the alice_keys list and shall return a list of 2^16 puzzles. 
 +def gen_puzzles(): 
 +  # TODO 
 + 
 +# TODO This is Bob. He tries to solve one random puzzle. His purpose is to solve one random puzzle 
 +# offered by Alice. 
 +# This function shall fill in the bob_key list with the secret discovered by Bob. 
 +# The function shall return ​the index of the chosen puzzle. 
 +def solve_puzzle(puzzles):​ 
 +  # TODO   
 + 
 +def main(): 
 +  # Alice generates some puzzles 
 +  puzzles = gen_puzzles() 
 +  # Bob solves one random puzzle and discovers the secret 
 +  x = solve_puzzle(puzzles) 
 +  print "​Bob'​s secret key: " + bob_key[0] 
 +  # Alice receives the puzzle index from Bob and now knows the secret 
 +  print "​Alice'​s secret key: " + alice_keys[x] 
 +  # The secret should be the sameeven if it was not explicitly shared 
 +  if bob_key[0] == alice_keys[x]:​ 
 +    print ":)
 +  else: 
 +    ​print ":​("​ 
 + 
 +if __name__ == "​__main__":​ 
 +  main() 
 + 
 +</​file>​ 
 + 
 +<​hidden>​ 
 +The solution is {{:​ic:​laboratoare:​lab11_sol.zip|here}}. 
 +</hidden>
sasc/laboratoare/10.1464078412.txt.gz · Last modified: 2016/05/24 11:26 by sergiu.costea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0