Example #1
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
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 #3
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)
Example #4
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 #5
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 #6
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 #7
0
 def _a(self, secret, hash_algorithm, n, seed):
     if n == 0:
         return seed
     else:
         h = HMAC(secret, hash_algorithm, default_backend())
         h.update(self._a(secret, hash_algorithm, n - 1, seed))
         return h.finalize()
Example #8
0
    def _encrypt_from_parts(self,
                            data,
                            adata="",
                            salt="",
                            signing_key="",
                            encryption_key=""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        # print("signing_key = " + str(len(signing_key)), signing_key)
        # print("encryption_key = " + str(len(encryption_key)), encryption_key)
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(algorithms.AES(encryption_key), modes.CBC("0" * 16),
                           self._backend).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (b"\x82" + salt + ctx)

        h = HMAC(signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts + adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + tag)
Example #9
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 #10
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 #11
0
    def sign(self, pairs):
        """
        Generate a signature for a sequence of (key, value) pairs


        @param pairs: The pairs to sign, in order
        @type pairs: Iterable[six.text_type, six.text_type], six.binary_type is deprecated

        @return: The binary signature of this sequence of pairs
        @rtype: six.binary_type
        """
        warning_msg = "Binary values for pairs are deprecated. Use text input instead."
        pairs = [(string_to_text(a,
                                 warning_msg), string_to_text(b, warning_msg))
                 for a, b in pairs]
        kv = kvform.seqToKV(pairs)

        try:
            algorithm = self.hmac_algorithms[self.assoc_type]
        except KeyError:
            raise ValueError('Unknown association type: %r' %
                             (self.assoc_type, ))

        hmac = HMAC(self.secret, algorithm, backend=default_backend())
        hmac.update(kv.encode('utf-8'))
        return hmac.finalize()
Example #12
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 #13
0
def aes_cbc_dec(aesKey, bsEncMsg, bsMacMsg):
    '''
    AuthenticatedEncryption - Check mac then decrypt given encrypted message.
    '''
    ### Prepare for mac
    sha256 = SHA256()
    hmac = HMAC(aesKey, sha256, default_backend())
    ### do mac
    hmac.update(bsEncMsg)
    macMsg = hmac.finalize()
    if (macMsg != bsMacMsg):
        raise Exception("ERRR:AEDecrypt:Mismatch, skipping")
        return None
    ### Prepare for decryption
    blockLen = 16
    iv = os.urandom(blockLen)
    aes = AES(aesKey)
    cbc = CBC(iv)
    aesCbc = Cipher(aes, cbc, default_backend())
    aesCbcDec = aesCbc.decryptor()
    ### do decrypt
    decMsg = aesCbcDec.update(bsEncMsg)
    decFina = aesCbcDec.finalize()
    decMsg = decMsg + decFina
    # do pkcs7 depadding
    unpad = PKCS7(blockLen * 8).unpadder()
    decMsg = unpad.update(decMsg)
    decMsg += unpad.finalize()
    # Discard the initial random block, as corresponding enc and this dec uses
    # non communicated random iv and inturn discardable random 0th block
    decMsg = decMsg[blockLen:]
    return decMsg
Example #14
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 #15
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 #16
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 #17
0
    def process_header(self, data):
        if self._cipher_key_len is None:
            if data[0:6] != FILEMAGIC:
                raise EncryptorError("Invalid magic bytes")
            self._cipher_key_len = struct.unpack(">H", data[6:8])[0]
        else:
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            try:
                plainkey = self.rsa_private_key.decrypt(data, 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._header_size = 8 + len(data)

            self.cipher = Cipher(algorithms.AES(key),
                                 modes.CTR(nonce),
                                 backend=default_backend()).decryptor()
            self.authenticator = HMAC(auth_key,
                                      SHA256(),
                                      backend=default_backend())
Example #18
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 #19
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 #20
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 #21
0
def _get_hmac(key, ciphertext, digest_method):
    hmac = HMAC(
        key,
        get_digest(digest_method),
        backend=default_backend()
    )
    hmac.update(ciphertext)
    return hmac.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 #23
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 #24
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 #25
0
def hmac(key, data, hash_alg, backend):
  h = HMAC(
    key,
    hash_alg,
    backend=backend
  )
  h.update(data)
  return h.finalize()
Example #26
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 #27
0
    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())
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 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 #30
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 #31
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 #32
0
    def __init__(self, key=None, iv=None):
        self.key = key or os.urandom(32)
        self.iv = iv or os.urandom(16)

        self.encryptor = Cipher(algorithms.AES(self.key[16:]),
                                modes.CBC(self.iv),
                                backend=default_backend()).encryptor()
        self.padder = padding.PKCS7(algorithms.AES.block_size).padder()
        self.hmac = HMAC(key[:16], hashes.SHA256(), backend=default_backend())
        self.header = False
Example #33
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 #34
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 #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 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 #38
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 #39
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 #40
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 #41
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 #42
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 #43
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 #44
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 #45
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 #46
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 #47
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 #48
0
def MyencryptMAC(message, EncKey, HMACKey):
    # encrypts message with encryption key
    c, iv = myencrypt(message, EncKey)

    if len(HMACKey) != KEY_BYTES:
        # prints error message
        sys.stderr.write('Error: HMAC key length must be 32 bytes.')
    else:
        # generates tag using HMAC on ciphertext generated above
        tag = HMAC(HMACKey, hashes.SHA256(), backend=default_backend())
        tag.update(c)
        tag = tag.finalize()

        return c, iv, tag
Example #49
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 #50
0
    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
Example #51
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 #52
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 #53
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 #54
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 #55
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
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 #57
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)
Example #58
0
  def decrypt(self, token, associated_data=b"", 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) != 0x81):
      raise InvalidToken

    h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
    h.update(data[:-32] + associated_data)
    try:
      h.verify(data[-32:])
    except InvalidSignature:
      raise InvalidToken
    iv = data[1:17]
    ciphertext = data[17:-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 #59
0
class Encryptor:
    def __init__(self, rsa_public_key_pem):
        if not isinstance(rsa_public_key_pem, bytes):
            rsa_public_key_pem = rsa_public_key_pem.encode("ascii")
        self.rsa_public_key = serialization.load_pem_public_key(rsa_public_key_pem, backend=default_backend())
        self.cipher = None
        self.authenticator = None

    def update(self, data):
        ret = b""
        if self.cipher is None:
            key = os.urandom(16)
            nonce = os.urandom(16)
            auth_key = os.urandom(32)
            self.cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).encryptor()
            self.authenticator = HMAC(auth_key, SHA256(), backend=default_backend())
            pad = padding.OAEP(mgf=padding.MGF1(algorithm=SHA1()),
                               algorithm=SHA1(),
                               label=None)
            cipherkey = self.rsa_public_key.encrypt(key + nonce + auth_key, pad)
            ret = FILEMAGIC + struct.pack(">H", len(cipherkey)) + cipherkey
        cur = self.cipher.update(data)
        self.authenticator.update(cur)
        if ret:
            return ret + cur
        else:
            return cur

    def finalize(self):
        if self.cipher is None:
            return b""  # empty plaintext input yields empty encrypted output

        ret = self.cipher.finalize()
        self.authenticator.update(ret)
        ret += self.authenticator.finalize()
        self.cipher = None
        self.authenticator = None
        return ret
Example #60
0
    def _encrypt_from_parts(self, data, adata="", salt = "", signing_key = "", encryption_key = ""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        # print("signing_key = " + str(len(signing_key)), signing_key)
        # print("encryption_key = " + str(len(encryption_key)), encryption_key)
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(encryption_key), modes.CBC("0"*16), self._backend
        ).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()

        basic_parts = (
            b"\x82" + salt + ctx
        )

        h = HMAC(signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts + adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        return base64.urlsafe_b64encode( basic_parts + tag )