NOTE: I originally posted this on Snipplr.

To HMAC, pass a hash from Crypto.Hash in PyCrypto. Key should be a bytes object. Returns a bytearray.

def pad_key(a_hash, a_key):
    block_size = a_hash.digest_size

    if (len(a_key) > block_size):
        a_hasher =
        return a_hasher.digest()
    elif (len(a_key) < block_size): 
        return a_key + (b'\x00' * (block_size - len(a_key)))

    return a_key

def HMAC(a_hash, a_key, data):
    block_size  = a_hash.digest_size
    a_key       = pad_key(a_hash, a_key)
    block_range = bytearray([i for i in range(block_size)])
    xor_5c      = bytearray.maketrans(block_range, bytearray([i ^ 0x5c for i in range(block_size)]))
    xor_36      = bytearray.maketrans(block_range, bytearray([i ^ 0x36 for i in range(block_size)]))

    inner_hasher =
    outer_hasher = inner_hasher.copy()
    final_hasher = inner_hasher.copy()

    inner_hasher.update(a_key.translate(xor_36) + data)
    outer_hasher.update(a_key.translate(xor_5c) + inner_hasher.digest())

    return bytearray(final_hasher.digest())