This is an old revision of the document!


Lab 08 - MACs

In this lab we'll do some exercises with Message Authentication Codes.

Exercise 1 - Existential Unforgeability

Exercise 2 - Birthday attack

Exercise 3 - Timing attack

In this exercise you will perform a timing attack against HMAC.

You are given access to an HMAC $\mathsf{Verify}$ oracle, which tests whether the received HMAC matches the one computed using the secret key. Timing attacks exploit naive equality comparisons between the received and computed HMACs (for example, the comparison is done byte by byte; more checks means more latency).

Your task is to produce a forged tag for the message 'Test' without knowing the key. Do this by iterating through all possible values for a specific byte; when the oracle's latency for a certain value seems larger than the rest, it suggests that the equality test returned True and the oracle passed to the next byte.

Try to start by finding the first byte and checking your result with the TA.

You can use time.clock() before and after each oracle query to measure its runtime.

The oracle's latency is subject to noise; for the best results, you will need to run each query multiple times (try at least 30) and compute the mean latency.

timing.py
import sys
import random
import string
import time
import itertools
import operator
import base64
 
from Crypto.Hash.HMAC import HMAC
 
def raw2hex(raw):
    return raw.encode('hex')
 
 
def hex2raw(hexstring):
    return base64.b16decode(hexstring)
 
 
def slow_foo():
    p = 181
    k = 2
    while k < p:
        if p % k == 0:
            return
        k += 1
 
 
def verify(message, tag):
    k = '0123456789ABCDEF'
 
    # Use MD5 for HMAC
    digest = HMAC(k, message).digest()
 
    for i in range(16):
        # Artificially expand byte comparison duration
        slow_foo()
        if tag[i] != digest[i]:
            return False
 
    return True
 
 
hexdigits = '0123456789ABCDEF'
 
 
def main():
    message = 'Test'
 
    # Step 1. Iterate through all possible first byte values, and call the
    # Verify oracle for each of them
 
    # Step 2. Store the byte which caused the longest computation time
 
    # Step 3. Continue the operation for each byte (except the last)
 
    # Step 4. Guess the last byte, and query the oracle with the complete tag
    mytag = '???'
    result = verify(message, mytag)
    if result == True:
        print mytag
 
 
if __name__ == "__main__":
    main()
sasc/laboratoare/08.1461623374.txt.gz · Last modified: 2016/04/26 01:29 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