def salted_hmac(key_salt, value, secret=None):
    """
    Returns the HMAC-HASH of 'value', using a key generated from key_salt and a
    secret (which defaults to settings.SECRET_KEY).

    A different key_salt should be passed in for every application of HMAC.

    :type key_salt: any
    :type value: any
    :type secret: any
    :rtype: HMAC
    """
    if secret is None:
        secret = settings.SECRET_KEY

    key_salt = force_bytes(key_salt)
    secret = force_bytes(secret)

    # We need to generate a derived key from our base key.  We can do this by
    # passing the key_salt and our base key through a pseudo-random function and
    # SHA1 works nicely.
    digest = hashes.Hash(settings.CRYPTOGRAPHY_DIGEST,
                         backend=settings.CRYPTOGRAPHY_BACKEND)
    digest.update(key_salt + secret)
    key = digest.finalize()

    # If len(key_salt + secret) > sha_constructor().block_size, the above
    # line is redundant and could be replaced by key = key_salt + secret, since
    # the hmac module does the same thing for keys longer than the block size.
    # However, we need to ensure that we *always* do this.
    h = HMAC(key, settings.CRYPTOGRAPHY_DIGEST,
             backend=settings.CRYPTOGRAPHY_BACKEND)
    h.update(force_bytes(value))
    return h
Example #2
0
    def check_integrity(self, token, ttl=None):
        # check integrity of files
        # with our implementation, this is actually superfluous, since if the integrity is compromised, you can't get to
        # this function. We check the integrity when we decrypt.
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")

        current_time = int(time.time())

        try:
            data = base64.urlsafe_b64decode(token)
        except (TypeError, binascii.Error):
            raise InvalidToken

        if not data or six.indexbytes(data, 0) != 0x80:
            raise InvalidToken

        try:
            timestamp, = struct.unpack(">Q", data[1:9])
        except struct.error:
            raise InvalidToken
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA512(), backend=self._backend)
        h.update(data[:-64])
        try:
            h.verify(data[-64:])
        except InvalidSignature:
            raise InvalidToken
Example #3
0
    def encrypt_with_hmac(self, data, data_id, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        if not isinstance(data_id, int):
            raise TypeError("data_id must be int.")

        main_parts = (
            struct.pack(config.FORMAT_CHAR, data_id) + data
        )

        # PKCS7 padding
        padded_data = self.add_padding(main_parts, algorithms.AES.block_size)
        # AES with CBC mode
        encryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), backend=self.backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + iv + ciphertext
        )

        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Example #4
0
    def decrypt_encryption_key_fallback(self):
        """Decrypts the encryption key using the FALLBACK method. In this method, the
        context string, usually "CredEncryption" or "PSEEncryption", is encrypted using
        a derivation of a fixed key hardcoded in CommonCryptoLib, and used as key to
        encrypt the actual encryption key used in the file with the AES cipher.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with FALLBACK LPS mode")

        digest = Hash(SHA1(), backend=default_backend())
        digest.update(cred_key_lps_fallback)
        hashed_key = digest.finalize()

        hmac = HMAC(hashed_key, SHA1(), backend=default_backend())
        hmac.update(self.context)
        default_key = hmac.finalize()[:16]

        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(default_key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        encryption_key = decryptor.update(
            self.encrypted_key) + decryptor.finalize()

        return encryption_key
Example #5
0
    def scramble_salt(self,
                      password,
                      salt,
                      server_key,
                      client_key,
                      rounds=None):
        """Scrambles a given salt using the specified server key.
        """
        msg = salt + server_key + client_key

        hmac_digest = self.salt_key(password, salt, rounds)

        hash = Hash(self.ALGORITHM(), self.backend)
        hash.update(hmac_digest)
        hash_digest = hash.finalize()

        key_hash = Hash(self.ALGORITHM(), self.backend)
        key_hash.update(hash_digest)
        key_hash_digest = key_hash.finalize()

        sig = HMAC(key_hash_digest, self.ALGORITHM(), self.backend)
        sig.update(msg)
        sig_digest = sig.finalize()

        return self.xor(sig_digest, hash_digest)
Example #6
0
    def _decrypt_data(self, data, timestamp, ttl):
        current_time = int(time.time())
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(data[:-32])
        try:
            h.verify(data[-32:])
        except InvalidSignature:
            raise InvalidToken

        iv = data[9:25]
        ciphertext = data[25:-32]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Example #7
0
def salted_hmac(key_salt, value, secret=None):
    """
    Returns the HMAC-HASH of 'value', using a key generated from key_salt and a
    secret (which defaults to settings.SECRET_KEY).

    A different key_salt should be passed in for every application of HMAC.

    :type key_salt: any
    :type value: any
    :type secret: any
    :rtype: HMAC
    """
    if secret is None:
        secret = settings.SECRET_KEY

    key_salt = force_bytes(key_salt)
    secret = force_bytes(secret)

    # We need to generate a derived key from our base key.  We can do this by
    # passing the key_salt and our base key through a pseudo-random function and
    # SHA1 works nicely.
    digest = hashes.Hash(settings.CRYPTOGRAPHY_DIGEST,
                         backend=settings.CRYPTOGRAPHY_BACKEND)
    digest.update(key_salt + secret)
    key = digest.finalize()

    # If len(key_salt + secret) > sha_constructor().block_size, the above
    # line is redundant and could be replaced by key = key_salt + secret, since
    # the hmac module does the same thing for keys longer than the block size.
    # However, we need to ensure that we *always* do this.
    h = HMAC(key,
             settings.CRYPTOGRAPHY_DIGEST,
             backend=settings.CRYPTOGRAPHY_BACKEND)
    h.update(force_bytes(value))
    return h
Example #8
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        # PROBLEM: MAC-then-Encrypt

        # HMAC(HDR+R)
        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        basic_parts = (b"\x80" + struct.pack(">Q", current_time) + data)
        h.update(basic_parts)
        hmac = h.finalize()

        # R+T+pad
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data + hmac) + padder.finalize()

        print('Message:',
              data,
              'MAC:',
              hmac,
              'Pad:',
              padded_data[len(data + hmac):],
              sep=' ')
        print('Plaintext to be encrypted: ', padded_data)
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv),
                           self._backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        final_message = b"\x80" + \
            struct.pack(">Q", current_time) + iv + ciphertext

        return base64.urlsafe_b64encode(final_message)
Example #9
0
def encrypt(pubkey, data):
    public_key = _pub_to_public(pubkey)
    private_key = ec.generate_private_key(ec.SECP256K1(), openssl.backend)
    secret = private_key.exchange(ec.ECDH(), public_key)
    key = hashlib.sha512(secret).digest()
    enckey = key[0:32]
    mackey = key[32:64]
    iv = os.urandom(16)
    padder = padding.PKCS7(128).padder()
    paddeddata = padder.update(data) + padder.finalize()
    cipher = Cipher(algorithms.AES(enckey), modes.CBC(iv), openssl.backend)
    encryptor = cipher.encryptor()
    ciphertext = encryptor.update(paddeddata) + encryptor.finalize()
    s = serialize.Serializer()
    s.bytes(iv)
    s.uint(0x02ca, 2)
    public_numbers = private_key.public_key().public_numbers()
    x = public_numbers.x.to_bytes(32, 'big').lstrip(b'\x00')
    s.uint(len(x), 2)
    s.bytes(x)
    y = public_numbers.y.to_bytes(32, 'big').lstrip(b'\x00')
    s.uint(len(y), 2)
    s.bytes(y)
    s.bytes(ciphertext)
    maccer = HMAC(mackey, hashes.SHA256(), openssl.backend)
    maccer.update(s.data)
    mac = maccer.finalize()
    s.bytes(mac)
    return s.data
Example #10
0
def decrypt(privkey, data):
    s = serialize.Deserializer(data)
    iv = s.bytes(16)
    curve = s.uint(2)
    assert curve == 0x02ca
    x_len = s.uint(2)
    assert x_len <= 32 # TODO Should we assert this? And should we assert no leading zero bytes?
    x = s.bytes(x_len)
    y_len = s.uint(2)
    assert y_len <= 32 # TODO Should we assert this? And should we assert no leading zero bytes?
    y = s.bytes(y_len)
    encrypted = s.bytes(-32)
    assert encrypted != b''
    mac = s.bytes(32)
    pubkey = x.rjust(32, b'\x00') + y.rjust(32, b'\x00')
    public_key = _pub_to_public(pubkey)
    private_key = _priv_to_private(privkey)
    secret = private_key.exchange(ec.ECDH(), public_key)
    key = hashlib.sha512(secret).digest()
    enckey = key[0:32]
    mackey = key[32:64]
    maccer = HMAC(mackey, hashes.SHA256(), openssl.backend)
    maccer.update(data[0:-32])
    maccer.verify(mac)
    cipher = Cipher(algorithms.AES(enckey), modes.CBC(iv), openssl.backend)
    decryptor = cipher.decryptor()
    padded = decryptor.update(encrypted) + decryptor.finalize()
    unpadder = padding.PKCS7(128).unpadder()
    return unpadder.update(padded) + unpadder.finalize()
Example #11
0
def decrypt_ctr(key, iv, aad, data):
    """
    verify HMAC and decrypt using CTR mode

    key: 16 byte key
    iv: 12 bytes nonce. 4 zero bytes are appended to create the 16 byte
        nonce used for CTR mode
    aad: bytes. additional unencrypted data to include in the signature
    data: bytes. plaint text to encrypt

    """
    nonce = iv + b'\x00\x00\x00\x00'
    ct = data[:-16]
    tag = data[-16:]

    h = HMAC(key, SHA256(), backend=default_backend())
    h.update(aad)
    h.update(ct)
    act = h.finalize()[:16]

    if not bytes_eq(tag, act):
        raise ValueError()

    decryptor = Cipher(AES(key), CTR(nonce),
        backend=default_backend()).decryptor()

    return decryptor.update(ct) + decryptor.finalize()
Example #12
0
def encrypt_ctr(key, iv, aad, data):
    """
    encrypt using CTR then sign with an HMAC

    Note: this implementation is similar to AES-CCM, but is slower.
    The implementation is left in only for benchmarking purposes.

    Note: in theory this should parallize well, however in practice
    it is about 2x slower than GCM mode. The HMAC is not the bottleneck

    key: 16 byte key
    iv: 12 bytes nonce. 4 zero bytes are appended to create the 16 byte
        nonce used for CTR mode
    aad: bytes. additional unencrypted data to include in the signature
    data: bytes. plaint text to encrypt

    future work: require key to be 32 bytes, and then use
        16 bytes for the HMAC and the other 16 bytes for CTR mode
    """
    nonce = iv + b'\x00\x00\x00\x00'

    encryptor = Cipher(AES(key), CTR(nonce),
        backend=default_backend()).encryptor()

    ct = encryptor.update(data) + encryptor.finalize()

    h = HMAC(key, SHA256(), backend=default_backend())
    h.update(aad)
    h.update(ct)
    tag = h.finalize()[:16]

    return ct + tag
Example #13
0
 def _verify_signature(self, data):
     h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
     h.update(data[:-32])
     try:
         h.verify(data[-32:])
     except InvalidSignature:
         raise InvalidToken
Example #14
0
    def enc(self, byts):
        '''
        Encrypt the given bytes and return an envelope dict in msgpack form.

        Args:
            byts (bytes): The message to be encrypted.

        Returns:
            bytes: The encrypted message. This is a msgpacked dictionary
            containing the IV, ciphertext and HMAC values.
        '''
        iv = os.urandom(16)

        # pad the bytes using PKCS7
        padr = padding.PKCS7(self.bsize).padder()
        byts = padr.update(byts) + padr.finalize()

        mode = modes.CBC(iv)
        algo = algorithms.AES(self.ekey)
        encr = Cipher(algo, mode, self.bend).encryptor()

        # encrypt the bytes and prepend the IV
        byts = encr.update(byts) + encr.finalize()

        macr = HMAC(self.skey, hashes.SHA256(), backend=self.bend)
        macr.update(iv + byts)

        hmac = macr.finalize()
        envl = {'iv': iv, 'hmac': hmac, 'data': byts}
        return s_msgpack.en(envl)
    def checkHMAC(self, fp, segments_start, segments_end, fileHMAC):
        '''Check the file's integrity'''
        filehash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
        filehash.update(self.FileMACPrefix)
        for segmentIndex, startpos, datalen in self.segment_ranges(segments_start, segments_end):

            print("        Segment %d" % (segmentIndex))
            fp.seek(startpos)
            segmentIV = fp.read(self.SegIVLen)
            segmentMAC = fp.read(self.SegMACLen)

            # Verify the segment's own MAC against the segment data
            segmenthash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
            segmenthash.update(segmentIV)
            segmenthash.update(struct.pack('>I', segmentIndex))
            segmenthash.update(fp.read(datalen))

            # The cryptography module doesn't handle truncated HMACs directly
            computed = segmenthash.finalize()
            assert primitives.constant_time.bytes_eq(computed[:self.SegMACLen], segmentMAC)

            # Add the segment's MAC to the file-MAC context
            filehash.update(segmentMAC)

        # Finally, verify the file MAC
        print("        File hash")
        filehash.verify(fileHMAC) # Raises on mismatch.
def verifyThenDecrypt(cipher, emailTime, key):
	encryptKey = key[16:]
	signKey = key[:16]
	payload = base64.urlsafe_b64decode(cipher)

	#verify timestamp to prevent replay
	try:
		timestamp, = struct.unpack(">Q", payload[1:9])
	except struct.error:
		raise ValueError('Invalid message')
	if timestamp + TTL < emailTime:
		raise Exception('Invalid timestamp: replay attack detected')

	#verify HMAC
	hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend())
	hasher.update(payload[:-32])
	try:
		hasher.verify(payload[-32:])
	except InvalidSignature:
		raise Exception('Invalid HMAC: data modification detected')

	#decrypt cipher text
	iv = payload[9:25]
	ciphertext = payload[25:-32]
	decryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv), default_backend()).decryptor()
	paddedPlaintext = decryptor.update(ciphertext)
	paddedPlaintext += decryptor.finalize()
	unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
	plaintext = unpadder.update(paddedPlaintext)
	plaintext += unpadder.finalize()

	return plaintext
Example #17
0
 def _verify_signature(self, data):
     h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
     h.update(data[:-32])
     try:
         h.verify(data[-32:])
     except InvalidSignature:
         raise InvalidToken
Example #18
0
    def checkHMAC(self, fp, segments_start, segments_end, fileHMAC):
        '''Check the file's integrity'''
        filehash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
        filehash.update(self.FileMACPrefix)
        for segmentIndex, startpos, datalen in self.segment_ranges(segments_start, segments_end):

            print("        Segment %d" % (segmentIndex))
            fp.seek(startpos)
            segmentIV = fp.read(self.SegIVLen)
            segmentMAC = fp.read(self.SegMACLen)

            # Verify the segment's own MAC against the segment data
            segmenthash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend)
            segmenthash.update(segmentIV)
            segmenthash.update(struct.pack('>I', segmentIndex))
            segmenthash.update(fp.read(datalen))

            # The cryptography module doesn't handle truncated HMACs directly
            computed = segmenthash.finalize()
            assert primitives.constant_time.bytes_eq(computed[:self.SegMACLen], segmentMAC)

            # Add the segment's MAC to the file-MAC context
            filehash.update(segmentMAC)

        # Finally, verify the file MAC
        print("        File hash")
        filehash.verify(fileHMAC) # Raises on mismatch.
Example #19
0
class FernetDecryptMiddleware(BaseMiddleware):
    """ Decrypt data based on Fernet from the Cryptography library.

        - Algorithm: AES-128
        - Mode: CBC
        - Padding: PKCS#7
        - MAC: SHA-256, Encrypt-then-MAC
        - Key: User-provided
        - IV: First 16-bytes of data

    """

    readable = True

    def __init__(self, key, iv=None):
        self.key = key
        self.iv = iv
        self.check = b''

        self.decryptor = None

        self.unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
        self.hmac = HMAC(key[:16], hashes.SHA256(), backend=default_backend())

    def flush(self):
        if self.decryptor:
            data = self.decryptor.finalize()
            self.decryptor = None
            self.hmac.update(data)
            self.hmac.verify(self.check)
            if data:
                return self.unpadder.update(data) + self.unpadder.finalize()
            else:
                return self.unpadder.finalize()
        return b''

    def read(self, data):
        if not self.decryptor:
            if len(data) < 16:
                self.iv = data
                return b''
            else:
                self.iv = data[:16]
                data = data[16:]

            self.decryptor = Cipher(algorithms.AES(self.key[16:]),
                                    modes.CBC(self.iv),
                                    backend=default_backend()).decryptor()

        if not data:
            return b''

        data = self.check + data
        self.check = data[-32:]
        data = data[:-32]

        self.hmac.update(data)
        data = self.decryptor.update(data)
        return self.unpadder.update(data)
Example #20
0
def _get_hmac(key, ciphertext, digest_method):
    hmac = HMAC(
        key,
        get_digest(digest_method),
        backend=default_backend()
    )
    hmac.update(ciphertext)
    return hmac.finalize()
Example #21
0
def hmac_verify(key, data, hash_alg, backend, sig = None):
  h = HMAC(
    key,
    hash_alg,
    backend=backend
  )
  h.update(data)
  return h.verify(sig)
Example #22
0
 def signature(self, value):
     """
     :type value: any
     :rtype: HMAC
     """
     h = HMAC(self.key, self.digest, backend=settings.CRYPTOGRAPHY_BACKEND)
     h.update(force_bytes(value))
     return h
Example #23
0
def hmac(key, data, hash_alg, backend):
  h = HMAC(
    key,
    hash_alg,
    backend=backend
  )
  h.update(data)
  return h.finalize()
 def signature(self, value):
     """
     :type value: any
     :rtype: HMAC
     """
     h = HMAC(self.key, self.digest, backend=settings.CRYPTOGRAPHY_BACKEND)
     h.update(force_bytes(value))
     return h
Example #25
0
def _get_hmac(key, ciphertext, digest_method):
    hmac = HMAC(
        key,
        get_digest(digest_method),
        backend=default_backend()
    )
    hmac.update(ciphertext)
    return hmac.finalize()
Example #26
0
def _verify(data, mac_key):
    h = HMAC(mac_key, _MAC_HASH, _backend)
    h.update(data[:-_MAC_LEN])
    try:
        h.verify(data[-_MAC_LEN:])
        return True
    except InvalidSignature:
        return False
Example #27
0
class Decryptor(object):
    def __init__(self, rsa_private_key_pem):
        if not isinstance(rsa_private_key_pem, bytes):
            rsa_private_key_pem = rsa_private_key_pem.encode("ascii")
        self.rsa_private_key = serialization.load_pem_private_key(
            data=rsa_private_key_pem,
            password=None,
            backend=default_backend())
        self.cipher = None
        self.authenticator = None
        self.buf = b""

    def update(self, data):
        self.buf += data
        if self.cipher is None:
            if len(self.buf) < 8:
                return b""
            if self.buf[0:6] != FILEMAGIC:
                raise EncryptorError("Invalid magic bytes")
            cipherkeylen = struct.unpack(">H", self.buf[6:8])[0]
            if len(self.buf) < 8 + cipherkeylen:
                return b""
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            try:
                plainkey = self.rsa_private_key.decrypt(self.buf[8:8 + cipherkeylen], pad)
            except AssertionError:
                raise EncryptorError("Decrypting key data failed")
            if len(plainkey) != 64:
                raise EncryptorError("Integrity check failed")
            key = plainkey[0:16]
            nonce = plainkey[16:32]
            auth_key = plainkey[32:64]

            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).decryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())
            self.buf = self.buf[8 + cipherkeylen:]

        if len(self.buf) < 32:
            return b""

        self.authenticator.update(self.buf[:-32])
        result = self.cipher.update(self.buf[:-32])
        self.buf = self.buf[-32:]

        return result

    def finalize(self):
        if self.cipher is None:
            return b""  # empty encrypted input yields empty plaintext output
        elif self.buf != self.authenticator.finalize():
            raise EncryptorError("Integrity check failed")
        result = self.cipher.finalize()
        self.buf = b""
        self.cipher = None
        self.authenticator = None
        return result
Example #28
0
    def __call__(self, request):
        hmac = HMAC(self.secret.encode('utf-8'), SHA512(), default_backend())
        hmac.update(request.body.encode('utf-8'))
        signature = hexlify(hmac.finalize())

        request.headers['Key'] = self.key
        request.headers['Sign'] = signature

        return request
Example #29
0
def verify_hmac(key, data, signature):
    """Shortcut for verifying HMAC of a string."""
    h = HMAC(
        key=key,
        algorithm=hashes.SHA256(),
        backend=backend
    )
    h.update(data)
    return h.verify(signature)
Example #30
0
def calculate_hmac(key, data):
    """Shortcut for calculating HMAC of a string."""
    h = HMAC(
        key=key,
        algorithm=hashes.SHA256(),
        backend=backend
    )
    h.update(data)
    return h.finalize()
Example #31
0
def MyencryptMAC(plaintext, key, HMACkey):
    #if(len(key) < 32):
    #return "ERROR: Key must be 32 Bytes or bigger"
    #HMAC: maybe replace plaintext to key.encode() according to lab instructions
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(plaintext)
    h = HMAC(HMACkey, hashes.SHA256(), backend=default_backend())
    h.update(plaintext.encode())
    tag = h.finalize()
    return (ciphertext, iv, tag)
Example #32
0
def symmetric_encrypt(data, key, hmac_key=None):
    if hmac_key:
        prefix = randbytes(3)
        hmac = HMAC(hmac_key, SHA1(), backend)
        hmac.update(prefix + data)
        iv = hmac.finalize()[:13] + prefix
    else:
        iv = randbytes(16)

    return symmetric_encrypt_with_iv(data, key, iv)
Example #33
0
 def _p_hash(self, hash_algorithm, secret, seed, output_length):
     result = bytearray()
     i = 1
     while len(result) < output_length:
         h = HMAC(secret, hash_algorithm, default_backend())
         h.update(self._a(secret, hash_algorithm, i, seed))
         h.update(seed)
         result.extend(h.finalize())
         i += 1
     return bytes(result[:output_length])
Example #34
0
def derive_keyhash_v2(domain, password, salt, iterations):
    kdf = PBKDF2HMAC(algorithm=SHA512(),
                     length=64,
                     salt=salt,
                     iterations=iterations,
                     backend=_CRYPTO_BACKEND)
    derived_key = kdf.derive((domain + password).encode('utf-8'))
    hf = HMAC(derived_key, SHA256(), backend=_CRYPTO_BACKEND)
    hf.update(domain.encode('utf-8'))
    return hf.finalize()
Example #35
0
def aes_cbc_enc(aesKey, sPlainMsg):
    '''
    AuthenticatedEncryption - Do a encrypt then mac operation on given message.

        a random iv is generated but not transmitted, instead a random block is
        prepended to the message and encrypted. Inturn the same can be discarded
        during decrypting. Each CBC block depends on the previous encrypted block
        so the 0th block acts as a inplace iv at one level.

        Encryption uses AES in CBC mode with PKCS7 padding where required.
        MAC uses HMAC with SHA256

            As encryption and mac using independent algorithms so the key is
            shared wrt encryption and mac operations.

        With aes length of key passed is independent of the block size used, and
        user can use any valid aes key size.

        This is similar to the age old encrypt as well as sign messages to ensure
        confidentiality as well as authenticity. But then instead of using asymm
        logic for signing, use a hash with hidden key based logic. Also make sure
        that one checks the authenticity before trying to use it or work on it, so
        that new oracles arent opened up, beyond the minimal unavoidable oracle.
    '''
    ### Prepare for encryption
    blockLen = 16
    iv = os.urandom(blockLen)
    aes = AES(aesKey)
    cbc = CBC(iv)
    aesCbc = Cipher(aes, cbc, default_backend())
    aesCbcEnc = aesCbc.encryptor()
    random0thBlock = os.urandom(blockLen)
    # This allows iv to be discarded
    # so also while decrypting discard the 0th block
    plainMsg = random0thBlock + sPlainMsg.encode('utf-8')
    # do PKCS7 padding
    if bInternalPadder:
        padLen = blockLen - (len(plainMsg) % blockLen)
        for i in range(padLen):
            plainMsg += int.to_bytes(padLen, 1, 'little')
    else:
        pad = PKCS7(blockLen * 8).padder()
        plainMsg = pad.update(plainMsg)
        plainMsg += pad.finalize()
    ### do encrypt
    encMsg = aesCbcEnc.update(plainMsg)
    encFina = aesCbcEnc.finalize()
    encMsg = encMsg + encFina
    ### Prepare for mac
    sha256 = SHA256()
    hmac = HMAC(aesKey, sha256, default_backend())
    ### do mac
    hmac.update(encMsg)
    macMsg = hmac.finalize()
    return encMsg, macMsg
Example #36
0
def _encrypt(enc_key, mac_key, salt, data, version):
    iv = os.urandom(_IV_LEN)
    padder = PKCS7(AES.block_size).padder()
    padded_data = padder.update(data) + padder.finalize()
    encryptor = Cipher(AES(enc_key), CBC(iv), _backend).encryptor()
    ciphertext = encryptor.update(padded_data) + encryptor.finalize()
    all_data = b''.join((version.value, salt, iv, ciphertext))
    h = HMAC(mac_key, _MAC_HASH, _backend)
    h.update(all_data)
    hmac = h.finalize()
    return all_data + hmac
Example #37
0
    def compute_verify_data(self, basekey, handshake_context):
        hash_len = self.hash.digest_size
        finished_key = self.expand_label(basekey, b"finished", b"", hash_len)

        h = Hash(self.hash, backend=default_backend())
        h.update(handshake_context)
        hash_value = h.finalize()

        hm = HMAC(finished_key, self.hash, default_backend())
        hm.update(hash_value)
        return hm.finalize()
Example #38
0
 def generate_mac(key, data, algorithm="SHA256", backend=BACKEND):
     """ Returns a message authentication code for verifying the integrity and
         authenticity of data by entities that possess the key. 
         
         Note this is a lower level function then apply_mac and
         only returns the mac itself. 
         
         The mac is generated via HMAC with the specified algorithm and key. """
     hasher = HMAC(key, getattr(hashes, algorithm.upper())(), backend=backend)
     hasher.update(algorithm + '::' + data)
     return hasher.finalize()
Example #39
0
def _check_hmac(
    halg: hashes.HashAlgorithm,
    hmackey: bytes,
    enc_cred: bytes,
    name: bytes,
    expected: bytes,
):
    h = HMAC(hmackey, halg(), backend=default_backend())
    h.update(enc_cred)
    h.update(name)
    h.verify(expected)
Example #40
0
    def compute_verify_data(self, basekey, handshake_context):
        hash_len = self.hash.digest_size
        finished_key = self.expand_label(basekey, b"finished", b"", hash_len)

        h = Hash(self.hash, backend=default_backend())
        h.update(handshake_context)
        hash_value = h.finalize()

        hm = HMAC(finished_key, self.hash, default_backend())
        hm.update(hash_value)
        return hm.finalize()
Example #41
0
    def decrypt(self: SSSSData, key: SSSSKey, name: str) -> bytes:
        keys = key.derive_keys(name)

        ct = self.ciphertext

        hm = HMAC(keys.hmac_key, SHA256(), backend = default_backend())
        hm.update(ct)
        hm.verify(self.mac)

        iv = IV(self.iv)
        return aes256ctr(iv, keys.aes_key, ct)
Example #42
0
def _a(secret, hash_algorithm, n, seed):
    """
    a() is defined as:
        a(0) = seed
        a(i) = HMAC_hash(secret, A(i-1))
    """
    if n == 0:
        return seed
    else:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, n - 1, seed))
        return h.finalize()
Example #43
0
    def decrypt(self, token, ttl=None):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")

        current_time = int(time.time())

        try:
            data = base64.urlsafe_b64decode(token)
        except (TypeError, binascii.Error):
            raise InvalidToken

        if not data or six.indexbytes(data, 0) != 0x80:
            raise InvalidToken

        try:
            timestamp, = struct.unpack(">Q", data[1:9])
        except struct.error:
            raise InvalidToken
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                print (">>>", current_time)
                print (">>>", timestamp)
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(data[:-32])
        try:
            # verify everything in data except for tag is the same as original
            h.verify(data[-32:])
        except InvalidSignature:
            raise InvalidToken

        iv = data[9:25]
        ciphertext = data[25:-32]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Example #44
0
 def get_shared_key(self, key_length=32, shared_secret=None):
     if not shared_secret and not self.shared_secret:
         raise ArithmeticError("No shared secret provided.")
     elif shared_secret and not self.shared_secret:
         self.shared_secret = shared_secret
     hash_provider = HMAC(
         hex(self.shared_secret).encode('utf-8'), SHA512(),
         default_backend())
     for i in range(0, 10000):
         hash_provider.update(hex(i).encode('utf-8'))
     shared_digest = base64.b64encode(hash_provider.finalize())
     return shared_digest[:key_length]
Example #45
0
File: prf.py Project: ashfall/tls
def _a(secret, hash_algorithm, n, seed):
    """
    a() is defined as:
        a(0) = seed
        a(i) = HMAC_hash(secret, A(i-1))
    """
    if n == 0:
        return seed
    else:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, n - 1, seed))
        return h.finalize()
Example #46
0
    def decrypt(self, token, ttl=None):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")

        current_time = int(time.time())

        try:
            data = base64.urlsafe_b64decode(token)
        except (TypeError, binascii.Error):
            raise InvalidToken

        if not data or six.indexbytes(data, 0) != 0x80:
            raise InvalidToken

        try:
            timestamp, = struct.unpack(">Q", data[1:9])
        except struct.error:
            raise InvalidToken
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                print(">>>", current_time)
                print(">>>", timestamp)
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(data[:-32])
        try:
            # verify everything in data except for tag is the same as original
            h.verify(data[-32:])
        except InvalidSignature:
            raise InvalidToken

        iv = data[9:25]
        ciphertext = data[25:-32]
        decryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv),
                           self._backend).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Example #47
0
 def verify_mac(key, packed_data, algorithm="SHA256", backend=BACKEND):
     """ Verifies a message authentication code as obtained by apply_mac.
         Successful comparison indicates integrity and authenticity of the data. 
         Returns data is comparison succeeds; Otherwise returns pride.functions.security.INVALID_TAG. """        
     mac, data = load_data(packed_data)
     hasher = HMAC(key, getattr(hashes, algorithm.upper())(), backend=backend)
     hasher.update(algorithm + '::' + data)
     try:
         hasher.verify(mac)
     except InvalidSignature:
         return INVALID_TAG
     else:
         return data
Example #48
0
    def _encrypt_cryptography(b_plaintext, b_key1, b_key2, b_iv):
        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), CRYPTOGRAPHY_BACKEND)
        encryptor = cipher.encryptor()
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize())
        b_ciphertext += encryptor.finalize()

        # COMBINE SALT, DIGEST AND DATA
        hmac = HMAC(b_key2, hashes.SHA256(), CRYPTOGRAPHY_BACKEND)
        hmac.update(b_ciphertext)
        b_hmac = hmac.finalize()

        return to_bytes(hexlify(b_hmac), errors='surrogate_or_strict'), hexlify(b_ciphertext)
Example #49
0
    def _encrypt_cryptography(b_plaintext, b_key1, b_key2, b_iv):
        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), CRYPTOGRAPHY_BACKEND)
        encryptor = cipher.encryptor()
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        b_ciphertext = encryptor.update(padder.update(b_plaintext) + padder.finalize())
        b_ciphertext += encryptor.finalize()

        # COMBINE SALT, DIGEST AND DATA
        hmac = HMAC(b_key2, hashes.SHA256(), CRYPTOGRAPHY_BACKEND)
        hmac.update(b_ciphertext)
        b_hmac = hmac.finalize()

        return to_bytes(hexlify(b_hmac), errors='surrogate_or_strict'), hexlify(b_ciphertext)
Example #50
0
File: prf.py Project: ashfall/tls
def _p_hash(hash_algorithm, secret, seed, output_length):
    """
    A seed expansion function that uses a single hash function to expand a
    secret and seed into the number of bytes specified by output_length.
    """
    result = bytearray()
    i = 1
    while len(result) < output_length:
        h = HMAC(secret, hash_algorithm, default_backend())
        h.update(_a(secret, hash_algorithm, i, seed))
        h.update(seed)
        result.extend(h.finalize())
        i += 1
    return bytes(result[:output_length])
Example #51
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if isinstance(data, six.text_type):
            raise TypeError("Unicode-objects must be encoded before encryption")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #52
0
def opdata1_verify_overall_hmac(hmac_key, item):
    verifier = HMAC(hmac_key, SHA256(), backend=_backend)
    for key, value in sorted(item.items()):
        if key == 'hmac':
            continue
        if isinstance(value, bool):
            value = str(int(value)).encode('utf-8')
        else:
            value = str(value).encode('utf-8')
        verifier.update(key.encode('utf-8'))
        verifier.update(value)
    expected = base64.b64decode(item['hmac'])
    try:
        verifier.verify(expected)
    except InvalidSignature:
        raise ValueError("HMAC did not match for data dictionary")
Example #53
0
def opdata1_decrypt_key(data, key, hmac_key, aes_size=C_AES_SIZE, ignore_hmac=False):
    """Decrypt encrypted item keys"""
    hmac_key = make_utf8(hmac_key)
    key_size = KEY_SIZE[aes_size]
    iv, cryptext, expected_hmac = struct.unpack("=16s64s32s", data)
    if not ignore_hmac:
        verifier = HMAC(hmac_key, SHA256(), backend=_backend)
        verifier.update(iv + cryptext)
        try:
            verifier.verify(expected_hmac)
        except InvalidSignature:
            raise ValueError("HMAC did not match for opdata1 key")
    aes = Cipher(algorithms.AES(key), modes.CBC(iv), backend=_backend)
    decryptor = aes.decryptor()
    decrypted = decryptor.update(cryptext) + decryptor.finalize()
    crypto_key, mac_key = decrypted[:key_size], decrypted[key_size:]
    return crypto_key, mac_key
Example #54
0
    def decrypt(self, data, ttl=None):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        current_time = int(time.time())

        if not data or six.indexbytes(data, 0) != 0x80:
            raise InvalidToken

        try:
            timestamp, = struct.unpack(">Q", data[1:9])
        except struct.error:
            raise InvalidToken
        if ttl is not None:
            if timestamp + ttl < current_time:
                raise InvalidToken

            if current_time + _MAX_CLOCK_SKEW < timestamp:
                raise InvalidToken

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(data[:-32])
        try:
            h.verify(data[-32:])
        except InvalidSignature:
            raise InvalidToken

        iv = data[9:25]
        ciphertext = data[25:-32]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
Example #55
0
    def _encrypt_from_parts(self, data, current_time, iv):
        utils._check_bytes("data", data)

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
        )

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)
Example #56
0
    def _decrypt_cryptography(cls, b_ciphertext, b_crypted_hmac, b_key1, b_key2, b_iv):
        # b_key1, b_key2, b_iv = self._gen_key_initctr(b_password, b_salt)
        # EXIT EARLY IF DIGEST DOESN'T MATCH
        hmac = HMAC(b_key2, hashes.SHA256(), CRYPTOGRAPHY_BACKEND)
        hmac.update(b_ciphertext)
        try:
            hmac.verify(unhexlify(b_crypted_hmac))
        except InvalidSignature as e:
            raise AnsibleVaultError('HMAC verification failed: %s' % e)

        cipher = C_Cipher(algorithms.AES(b_key1), modes.CTR(b_iv), CRYPTOGRAPHY_BACKEND)
        decryptor = cipher.decryptor()
        unpadder = padding.PKCS7(128).unpadder()
        b_plaintext = unpadder.update(
            decryptor.update(b_ciphertext) + decryptor.finalize()
        ) + unpadder.finalize()

        return b_plaintext
Example #57
0
  def __init__(self, key, backend=None):
    if backend is None:
      backend = default_backend()

    key = base64.urlsafe_b64decode(key)
    if len(key) != 32:
      raise ValueError(
        "Fernet key must be 32 url-safe base64-encoded bytes."
    )

    h = HMAC(key, hashes.SHA256(), backend=backend)
    h.update(b"\x00")
    self._signing_key = h.finalize()[:16]

    h = HMAC(key, hashes.SHA256(), backend=backend)
    h.update(b"\x01")
    self._encryption_key = h.finalize()[:16]

    self._backend = backend
def encryptThenMac(data, key):
	#set up keys, current timestamp and initialization vector
	encryptKey = key[16:]
	signKey = key[:16]
	curTime = int(time.time())
	iv = os.urandom(16)
	
	#pad the data and encrypt using AES in CBC mode
	padder = padding.PKCS7(algorithms.AES.block_size).padder()
	paddedData = padder.update(data) + padder.finalize()
	encryptor = Cipher(algorithms.AES(encryptKey), modes.CBC(iv), default_backend()).encryptor()
	cipher = encryptor.update(paddedData) + encryptor.finalize()
	
	#get the HMAC using SHA256 of the combined parts and return everything combined
	parts = (b"\x80" + struct.pack(">Q", curTime) + iv + cipher)
	hasher = HMAC(signKey, hashes.SHA256(), backend=default_backend())
	hasher.update(parts)
	hmac = hasher.finalize()
	return base64.urlsafe_b64encode(parts + hmac)
Example #59
0
    def _encrypt_from_parts(self, data, current_time, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
        )

        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return basic_parts + hmac
Example #60
0
  def _encrypt_from_parts(self, data, iv, associated_data):
    if not isinstance(data, bytes):
      raise TypeError("data must be bytes.")

    padder = padding.PKCS7(algorithms.AES.block_size).padder()
    padded_data = padder.update(data) + padder.finalize()
    encryptor = Cipher(
        algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
    ).encryptor()
    ciphertext = encryptor.update(padded_data) + encryptor.finalize()

    basic_parts = (
      b"\x81" + iv + ciphertext + associated_data
    )

    h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
    h.update(basic_parts)
    hmac = h.finalize() # TAG

    return base64.urlsafe_b64encode(b"\x81" + iv + ciphertext + hmac)