This shows you the differences between two versions of the page.
|
sasc:laboratoare:08 [2016/04/26 16:13] sergiu.costea [Exercise 2 - Timing attack] |
sasc:laboratoare:08 [2017/04/24 17:27] (current) dan.dragan |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Lab 08 - MACs ===== | + | ===== Lab 08 - MACs, Hashes, OpenSSL ===== |
| - | In this lab we'll do some exercises with Message Authentication Codes. | + | ==== Exercise 1 - Timing attack ==== |
| - | + | ||
| - | ==== Exercise 1 - Existential Unforgeability ==== | + | |
| - | + | ||
| - | In this exercise we will attack an insecure MAC algorithm by showing that an adversary can forge a (message, tag) pair without first querying a $\mathsf{Tag}$ oracle with the message. | + | |
| - | + | ||
| - | Let $F$ be a $\mathsf{PRF}$. Show that the following MAC is insecure by constructing an efficient adversary with non-negligible advantage. The key is $k \in \{0, 1\}^n$, and for any message $m = m1 \| m2$ with $\left|m_1\right| = \left|m_2\right| = n$, the MAC is computed as: | + | |
| - | + | ||
| - | $\mathsf{Tag}(k, m_1 \| m_2) = F_k(m_1) \| F_k(F_k(m_2)) $ | + | |
| - | ==== Exercise 2 - Timing attack ==== | + | |
| In this exercise you will perform a timing attack against CBC-MAC. | In this exercise you will perform a timing attack against CBC-MAC. | ||
| Line 27: | Line 18: | ||
| TODO1: Implement the CBC-MAC function. | TODO1: Implement the CBC-MAC function. | ||
| + | |||
| + | <note> | ||
| + | To check your implementation of CBC-MAC is correct, verify that this (plaintext,tag) verifies fine: | ||
| + | plaintext = 'Placinta de mere' | ||
| + | tag = '07d2771038d62b94fce106cff957da0f' (in hex, you need to apply decode to get a bytestream) | ||
| + | </note> | ||
| TODO2: Implement the MAC time verification attack and obtain the desired MAC without knowing the key. | TODO2: Implement the MAC time verification attack and obtain the desired MAC without knowing the key. | ||
| + | |||
| + | <note> | ||
| + | Try to print the resulting tag in hex (with tag.encode(hex)). It should start with 51 and end with 81. | ||
| + | </note> | ||
| <file python timing.py> | <file python timing.py> | ||
| Line 179: | Line 180: | ||
| verify(message, tag) | verify(message, tag) | ||
| - | # Step 2. Store the byte which caused the longest computation time | + | # Step 2. Store the byte that caused the longest computation time |
| # Step 3. Continue the operation for each byte (except the last) | # Step 3. Continue the operation for each byte (except the last) | ||
| Line 193: | Line 194: | ||
| </file> | </file> | ||
| - | ==== Exercise 3 - Birthday attack ==== | + | ==== Exercise 2 ==== |
| - | In this exercise you will perform a Birthday attack on SHA256. | + | In this first exercise we'll see how to compute hashes using the OpenSSL command line interface. |
| - | Your goal is to find two messages, $M_1$ and $M_2$, such that for the first **four** bytes $\mathsf{SHA256}(M_1) = \mathsf{SHA256}(M_2)$. | + | You can interact with the OpenSSL utilities in two ways: |
| + | * directly from bash, by using the ''openssl'' command followed by the desired command and parameters | ||
| + | * from the OpenSSL console, by using the ''openssl'' command without additional arguments. You can close the console by calling ''quit'' or ''exit''. | ||
| - | The collision will be $32$ bits long, which means you will need $2^{16}$ random messages in your attack. Note that the attack is not guaranteed to succeed; on average, two iterations of the attack are required to find a collision. | + | If the manual pages are correctly installed, you can consult the documentation via ''man <command_name>'' (e.g. ''man md5''). |
| - | <file python birthday.py> | ||
| - | import sys | + | Hashes are often used to check the integrity of downloaded files. We will now use OpenSSL to compute the MD5 and SHA-1 hashes of this page. |
| - | import string | + | |
| - | import base64 | + | |
| - | from Crypto.Hash import SHA256 | + | Download this page by running: |
| - | def raw2hex(raw): | + | <code> |
| - | return raw.encode('hex') | + | linux$ wget http://ocw.cs.pub.ro/courses/sasc/laboratoare/09 -O sasc.html |
| + | </code> | ||
| - | def hex2raw(hexstring): | + | Use OpenSSL to compute the MD5 and SHA-1 hashes of the newly downloaded file; print the output in hexadecimal. |
| - | return base64.b16decode(hexstring) | + | |
| - | hexdigits = '0123456789ABCDEF' | + | To check your results, you can use ''md5sum'' or ''sha1sum'' as an alternative way of computing the same hashes. |
| - | def hash(message): | + | ==== Exercise 3 ==== |
| - | h = SHA256.new() | + | |
| - | h.update(message) | + | |
| - | return h.digest() | + | |
| + | In this second exercise we'll use the command line to compute an HMAC, with SHA-1 as the hashing algorithm. | ||
| - | def main(): | + | Recall from the lecture that for HMAC to be secure, we need to sample a random key $k \gets \mathcal{K}$. |
| - | # Try to find a collision on the first 4 bytes (32 bits) | + | |
| - | + | ||
| - | # Step 1. Generate 2^16 different random messages | + | |
| - | + | ||
| - | # Step 2. Compute hashes | + | |
| - | + | ||
| - | # Step 3. Check if there exist two hashes that match in the first | + | |
| - | # four bytes. | + | |
| - | + | ||
| - | # Step 3a. If a match is found, print the messages and hashes | + | |
| - | + | ||
| - | # Step 3b. If no match is found, repeat the attack with a new set | + | |
| - | # of random messages | + | |
| - | pass | + | We can generate random bytes using ''openssl rand''. To compute HMACs, check the documentation for ''openssl dgst''. |
| - | if __name__ == "__main__": | + | For this exercise, use OpenSSL commands to: |
| - | main() | + | - generate a 16 byte random key |
| + | - use the key to compute the SHA-1 HMAC of the page downloaded in the previous exercise | ||
| - | </file> | + | |
| + | ==== Exercise 4 ==== | ||
| + | |||
| + | In this exercise you will implement the Birthday attack on SHA-1 from the previous lab using OpenSSL. The goal is to obtain a collision in the first four bytes of the hash. | ||
| + | |||
| + | In contrast to previous labs, this time we'll use C. You can implement the attack from scratch, or start from our {{:sasc:laboratoare:birthday.tar.gz|archive here}}. | ||
| + | |||
| + | To compute a digest, you might find the code below useful: | ||
| + | |||
| + | <code C> | ||
| + | SHA_CTX context; | ||
| + | SHA1_Init(&context); | ||
| + | SHA1_Update(&context, buffer, length); | ||
| + | SHA1_Final(md, &context); /* md must point to at least 20 bytes of valid memory */ | ||
| + | </code> | ||
| + | |||
| + | <note important> | ||
| + | To compile using OpenSSL you will need to install the development version of the library which includes the header files. | ||
| + | |||
| + | Download the library from https://www.openssl.org/source/old/1.0.1/openssl-1.0.1f.tar.gz, and unpack it. | ||
| + | |||
| + | 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 install_sw | ||
| + | </code> | ||
| + | |||
| + | To fix the makefile using the new paths, change the variables at the start with the ones below: | ||
| + | <code makefile> | ||
| + | LDFLAGS=-L/home/student/local/lib -lcrypto | ||
| + | CFLAGS=-Wall -g -I/home/student/local/include | ||
| + | </code> | ||
| + | </note> | ||