Beispiel #1
0
 def _run_tests(self, hash_type, reference_method):
     for i in range(hash_type().block_size // 8):
         for _ in range(100):
             key = Bytes.random(i * 8)
             in_bytes = Bytes.random(i * 32)
             samson_hash = HMAC(key=key, hash_obj=hash_type())
             self.assertEqual(
                 samson_hash.generate(in_bytes),
                 pyhmac.HMAC(key, in_bytes, reference_method).digest())
Beispiel #2
0
 def __init__(self,
              key: bytes,
              hash_obj: object = SHA1(),
              digits: int = 6,
              counter: object = IncrementingCounter(0)):
     """
     Parameters:
         key       (bytes): Shared key.
         hash_obj (object): Instantiated hash object.
         digits      (int): Number of digits to generate.
         counter     (int): Initial counter.
     """
     self.hmac = HMAC(key, hash_obj)
     self.digits = digits
     self.counter = counter
Beispiel #3
0
    def encrypt_and_auth(self, key: bytes, iv: bytes, plaintext: bytes,
                         auth_data: bytes) -> (Bytes, Bytes):
        mac_key, enc_key = key.chunk(self.chunk_size)

        rij = Rijndael(enc_key)
        cbc = CBC(rij, iv=iv)

        ciphertext = cbc.encrypt(plaintext)
        hmac = HMAC(
            mac_key,
            self.hash_obj).generate(auth_data + iv + ciphertext +
                                    Bytes(len(auth_data) *
                                          8).zfill(8))[:self.chunk_size]

        return ciphertext, hmac
Beispiel #4
0
    def derive(self, key: bytes, salt: bytes, info: bytes = b'') -> Bytes:
        """
        Derives a key.

        Parameters:
            key  (bytes): Bytes-like object to key the internal HMAC.
            salt (bytes): Salt to tweak the output.
            info (bytes): Additional data to use as tweak.
        
        Returns:
            Bytes: Derived key.
        """
        prk = HMAC(key=salt, hash_obj=self.hash_obj).generate(key)
        hmac = HMAC(key=prk, hash_obj=self.hash_obj)

        new_key = b''
        t = b''
        for i in range(
                math.ceil(self.desired_len /
                          (self.hash_obj.digest_size // 8))):
            t = hmac.generate(t + info + bytes([i + 1]))
            new_key += t

        return new_key[:self.desired_len]
Beispiel #5
0
    def decrypt(self, key: bytes, iv: bytes, ciphertext: bytes,
                auth_data: bytes, auth_tag: bytes) -> Bytes:
        mac_key, enc_key = key.chunk(self.chunk_size)

        hmac = HMAC(
            mac_key,
            self.hash_obj).generate(auth_data + iv + ciphertext +
                                    Bytes(len(auth_data) *
                                          8).zfill(8))[:self.chunk_size]

        assert RUNTIME.compare_bytes(hmac, auth_tag)

        rij = Rijndael(enc_key)
        cbc = CBC(rij, iv=iv)

        return cbc.decrypt(ciphertext)
Beispiel #6
0
    def _run_tests(self, hash_type, reference_method):
        hash_fn = lambda password, salt: HMAC(password, hash_type()).generate(
            salt)

        for i in range(hash_type().block_size // 8):
            for _ in range(5):
                password = Bytes.random(i * 8).zfill((i + 1) * 8)
                salt = Bytes.random(i * 2)
                desired_len = max(1, Bytes.random(1).int())
                num_iters = Bytes.random(1).int() % 256 + 1

                pbkdf2 = PBKDF2(hash_fn=hash_fn,
                                desired_len=desired_len,
                                num_iters=num_iters)
                self.assertEqual(
                    pbkdf2.derive(password, salt),
                    hashlib.pbkdf2_hmac(reference_method, password, salt,
                                        num_iters, desired_len))
Beispiel #7
0
        def oracle_func(h, r):
            h    = h.cache_mul(h.curve.cardinality().bit_length())
            K    = bob_key.derive_key(h)
            hmac = HMAC(key=K, hash_obj=sha256)
            mac  = hmac.generate(m)

            for i in range(r):
                eve_ecdhe.d = i
                eve_hmac    = HMAC(key=eve_ecdhe.derive_key(h), hash_obj=sha256)
                if eve_hmac.generate(m) == mac:
                    return i

            raise Exception(f'Residue not found for {r}!')
Beispiel #8
0
class HOTP(object):
    """
    HMAC-based One-Time Password (https://tools.ietf.org/html/rfc4226)
    """
    def __init__(self,
                 key: bytes,
                 hash_obj: object = SHA1(),
                 digits: int = 6,
                 counter: object = IncrementingCounter(0)):
        """
        Parameters:
            key       (bytes): Shared key.
            hash_obj (object): Instantiated hash object.
            digits      (int): Number of digits to generate.
            counter     (int): Initial counter.
        """
        self.hmac = HMAC(key, hash_obj)
        self.digits = digits
        self.counter = counter

    def __repr__(self):
        return f"<HOTP: hmac={self.hmac}, digits={self.digits}, counter={self.counter}>"

    def __str__(self):
        return self.__repr__()

    def generate(self) -> str:
        """
        Generates an OTP code as string of numbers (zero padded).

        Returns:
            str: OTP code.
        """
        ctr_hash = self.hmac.generate(
            Bytes.wrap(self.counter.get_value()).zfill(8))
        offset = ctr_hash[-1] & 0x0F
        code = ((ctr_hash[offset + 0] & 0x7F) << 24 |
                (ctr_hash[offset + 1] & 0xFF) << 16 |
                (ctr_hash[offset + 2] & 0xFF) << 8 |
                (ctr_hash[offset + 3] & 0xFF))

        return str(code % (10**self.digits)).zfill(self.digits)
Beispiel #9
0
 def __init__(self,
              desired_len: int,
              cost: int,
              parallelization_factor: int,
              block_size_factor: int = 8,
              hash_fn: FunctionType = lambda passwd, msg: HMAC(
                  passwd, SHA256()).generate(msg)):
     """
     Parameters:
         desired_len       (int): Desired output length.
         cost              (int): Cost (usually a power of two).
         block_size_factor (int): `r` from the RFC.
         hash_fn          (func): Function that takes in bytes and returns them hashed.
     """
     self.block_size = block_size_factor * 128
     self.hash_fn = hash_fn
     self.pbkdf2 = PBKDF2(hash_fn, self.block_size * parallelization_factor,
                          1)
     self.desired_len = desired_len
     self.cost = cost
     self.block_size_factor = block_size_factor
     self.parallelization_factor = parallelization_factor
Beispiel #10
0
 def sign(self, key: bytes, data: bytes) -> Bytes:
     return HMAC(hash_obj=self.hash_obj, key=key).generate(data)
Beispiel #11
0
 def __init__(self, hash_obj: object):
     self.hash_obj = hash_obj
     self.hash_fn = lambda key, msg: HMAC(key, self.hash_obj).generate(msg)
     self._underlying_cipher = JWA_AKW()