예제 #1
0
def hmac(key, message):
    padding_length = sha1.Sha1Hash.block_size - len(key)
    if padding_length > 0:
        key += '\x00' * padding_length
    else:
        key = sha1.Sha1Hash().update(key).digest()

    full_message = (
        xor(key, '\x5c' * len(key)) +
        sha1.Sha1Hash().update(xor(key, '\x36' * len(key))).digest() + message)

    return sha1.Sha1Hash().update(full_message).digest()
예제 #2
0
def calculate_hmac(file_name, key):
    if len(key) > block_size:
        key = sha1.Sha1Hash().update(key).digest()
    elif len(key) < block_size:
        key += '\x00' * (block_size - len(key))

    key = bytearray(key)

    o_key_pad = bytearray(len(key))
    i_key_pad = bytearray(len(key))

    for i in key:
        o_key_pad += bytearray([i ^ 0x5c])
        i_key_pad += bytearray([i ^ 0x36])

    i_key_hash = sha1.Sha1Hash().update(i_key_pad + file_name).digest()
    return sha1.Sha1Hash().update(o_key_pad + i_key_hash).digest()
예제 #3
0
def extend_sha1(old_digest, old_byte_length, extension):
    registers = tuple(int(old_digest[i:i + 8], 16)
                      for i in xrange(0, len(old_digest), 8))
    padding = compute_sha1_padding(old_byte_length)
    hasher = sha1.Sha1Hash()
    hasher._h = registers
    hasher._message_byte_length = old_byte_length + len(padding)
    hasher.update(extension)
    return (padding + extension, hasher.hexdigest())
예제 #4
0
def sha1_length_attack(message, mac, extension):
    registers = list(get_registers(mac))

    for i in xrange(0, 40):
        padded_text = sha1_pad(("A" * i) + message)
        forged_mac = sha1.Sha1Hash(h=registers, message_byte_length=len(padded_text)).update(extension).hexdigest()
        extended_message = padded_text[i:] + extension
        if validate_mac(extended_message, key, forged_mac) is True:
            return i, forged_mac

    return -1, ""
예제 #5
0
def main():
    sha1.Sha1Hash().update(b"a" * (64 * 2 - 1)).hexdigest()

    key = b"abc123"
    msg = b"green cup soup chef"

    correct = keyed_mac(key, msg)
    assert correct == "4860e61b1152e72910ab41f776df5c38940931a7"

    assert keyed_mac(b"abc124", msg) != correct
    assert keyed_mac(key, b"green cup soup chefs") != correct
예제 #6
0
def keyed_mac(key: bytes, msg: bytes) -> str:
    h0 = sha1.Sha1Hash()
    h0.update(key + msg)

    h1 = hashlib.sha1()
    h1.update(key + msg)

    d0 = h0.hexdigest()
    d1 = h1.hexdigest()

    assert d0 == d1

    return d0
예제 #7
0
def length_extension_attack(original_message: bytes, existing_hash: str,
                            guessed_length: int):
    extra = b";admin=true"
    glue_padding = compute_glue_padding(original_message, guessed_length)
    new_msg = original_message + glue_padding + extra

    prefix_length = guessed_length + len(original_message) + len(glue_padding)
    assert prefix_length % 64 == 0

    registers = to_registers(existing_hash)
    h = sha1.Sha1Hash(initial=registers)
    h._message_byte_length = prefix_length
    forged = h.update(extra).hexdigest()

    return forged, new_msg
def make_sha1_clone(hex_digest, known_suffix, est_len=None):
    ''' Given hex_digest and estimated length, clone SHAv1 hash.
        Important to note that state is only updated with each round of full
        64 bytes of message.
    '''
    # Instantiate clone
    clone = sha1.Sha1Hash()
    # State is output of digest.
    clone._h = tuple([int(hex_digest[i:i+8], 16)
                  for i in range(0, len(hex_digest), 8)])
    # Set estimated length of message; I figure most secret prefixes are 128
    # bit or less; there is some potential for edgecase problems here. That
    # can be controlled by manually setting len_state +/- 64 bytes.
    if not est_len:
        likely_len_state = (len(known_suffix) + 16) // 64
        likely_len_state = (likely_len_state * 64) + 64
    clone._message_byte_length = likely_len_state
    return clone
예제 #9
0
    def test_challenge29(self):
        secret_key = os.urandom(random.randint(1, 20))

        # Server returns the message and mac to the attacker
        message = 'comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon'
        mac = crypto.sha1_keyed_mac(secret_key, message)

        raw = convert.hex_to_bytes(mac)
        state = (
            bitops.from_bytes_be(raw[0:4]),
            bitops.from_bytes_be(raw[4:8]),
            bitops.from_bytes_be(raw[8:12]),
            bitops.from_bytes_be(raw[12:16]),
            bitops.from_bytes_be(raw[16:20]),
        )

        for guessed_key_length in xrange(1, 100):
            orig_message_length = guessed_key_length + len(message)
            padding = crack.sha1_padding(orig_message_length)

            # Attacker sets up a sha1 hash that is in the same state after
            # hashing secret_key + message + padding

            hasher = sha1.Sha1Hash()
            hasher._h = state
            hasher._message_byte_length = orig_message_length + len(padding)

            suffix = ';user=admin'
            falsified_mac = hasher.update(suffix).hexdigest()
            falsified_data = message + padding + suffix

            try:
                # Check to see if the server accepts the falsified data and MAC
                validate_mac(secret_key, falsified_data, falsified_mac,
                             crypto.sha1_keyed_mac)
                break
            except ValueError:
                # Guessed key length was wrong. Keep going...
                pass

        self.assertEqual(len(secret_key), guessed_key_length)
예제 #10
0
파일: test.py 프로젝트: Guyanqi/PyCrypto
    def test_associativity(self):
        """
        Test SHA-1 associativity
        Tests the fact that sha1(ab) is equivalent to sha1(a) updated with b.
        """
        print('\n>>> running: test_associativity')
        msg1 = bytearray(get_random_bytes())
        msg2 = bytearray(get_random_bytes())

        first_digest = sha1.sha1(bytes(msg1) + bytes(msg2))

        sha = sha1.Sha1Hash()
        sha.update(msg1)
        sha.update(msg2)

        second_digest = sha.hexdigest()

        print('... test_associativity: checking for identical digests')
        self.assertEqual(first_digest, second_digest)

        print('... test_associativity: success')
예제 #11
0
def validate_mac(message, key, mac):
    output_mac = sha1.Sha1Hash().update(key + message).hexdigest()
    if output_mac == mac:
        return True
    else:
        return False 
예제 #12
0
    # Pad the string until it is a multiple of 64 bytes with 2 words open
    padding += '\x00' * ((56 - (len(message) + 1) % 64) % 64)

    # Append the length of the bitstring in number of bits, big endian style
    padding += struct.pack(">Q", (len(message) * 8))

    return message + padding

def get_registers(mac):
    return struct.unpack(">IIIII", mac)

def sha1_length_attack(message, mac, extension):
    registers = list(get_registers(mac))

    for i in xrange(0, 40):
        padded_text = sha1_pad(("A" * i) + message)
        forged_mac = sha1.Sha1Hash(h=registers, message_byte_length=len(padded_text)).update(extension).hexdigest()
        extended_message = padded_text[i:] + extension
        if validate_mac(extended_message, key, forged_mac) is True:
            return i, forged_mac

    return -1, ""

if __name__ == "__main__":
    message = "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"
    mac = sha1.Sha1Hash().update(key + message).digest()

    key_len, forged_mac = sha1_length_attack(message, mac, ";admin=true")

    print("The key length is {} with a forged MAC of {}".format(key_len, forged_mac))
예제 #13
0
def authenticate(key, msg):
    return sha1.Sha1Hash().update(key + msg).digest()
예제 #14
0
import hashlib
import sha1
from util import keygen


def authenticate(key, msg):
    return sha1.Sha1Hash().update(key + msg).digest()


if __name__ == '__main__':
    sha = sha1.Sha1Hash().update('hello')
    print 'my implementation', sha.hexdigest()
    print 'expected', hashlib.sha1('hello').hexdigest()

    key = keygen()
    print authenticate(key, 'oh my gourd')
예제 #15
0
def auth(mac, message):
	if sha1.Sha1Hash().update(pkcs7(secret+message)).hexdigest() == mac: return True
	return False
예제 #16
0
def hash(ct, key):
    h = sha1.Sha1Hash()
    h.update(key+ct)
    return h.digest()