Example #1
0
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 #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 _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 #4
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 #5
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()
            # print(computed.decode("utf-8"))
            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 #6
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()
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
    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 #9
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 #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 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 #12
0
 def _verify_signature(self, data: bytes) -> None:
     h = HMAC(self._signing_key, hashes.SHA256())
     h.update(data[:-32])
     try:
         h.verify(data[-32:])
     except InvalidSignature:
         raise InvalidToken
Example #13
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 #14
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 #15
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 #16
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 #17
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 #18
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 #19
0
def verify_signature_hmac(signature, key, data):
    dt = _get_digest(signature.signature.hmac.hashAlg)
    if dt is None:
        raise ValueError(
            f"unsupported digest algorithm: {signature.signature.hmac.hashAlg}"
        )
    sh = hashes.Hash(dt(), backend=default_backend())
    sh.update(data)
    hdata = sh.finalize()
    sig = bytes(signature.signature.hmac)
    h = HMAC(key, dt(), backend=default_backend())
    h.update(hdata)
    h.verify(sig)
Example #20
0
    def compare(self, hmac, snowflake, secret):
        if not isinstance(hmac, bytes):
            hmac = base64.urlsafe_b64decode(hmac)
        if not isinstance(secret, bytes):
            secret = str(secret).encode()

        compare_hmac = HMAC(secret, hashes.SHA256(), backend=default_backend())
        compare_hmac.update(struct.pack('l', int(snowflake)))
        try:
            compare_hmac.verify(hmac)
            return True
        except:
            return False
Example #21
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 #22
0
def decrypt_and_unpack(
    input_file: IOIter,
    output_file: IOIter,
    key_pair: Optional[bytes],
    options: OptionsDict,
) -> None:
    """ Read encrypted, GZIPed data from an open file descriptor, and write the decoded data to
    another file descriptor; verify the HMAC of the encrypted data to ensure integrity

    :param input_file: an IOIter object to read compressed ciphertext from
    :param output_file: an IOIter object to write plaintext data to
    """
    key, nonce, signature = (
        key_pair[:AES_KEY_SIZE],
        key_pair[AES_KEY_SIZE:AES_KEY_SIZE + AES_BLOCK_SIZE],
        key_pair[AES_KEY_SIZE + AES_BLOCK_SIZE:]
    ) if key_pair else (b'', b'', b'')
    decrypted_data = b''
    decrypt_fn: Callable[[bytes], bytes] = (
        Cipher(AES(key), CTR(nonce), backend=default_backend()).decryptor().update
        if options['use_encryption'] else identity
    )
    decompress_obj = zlib.decompressobj()
    unzip_fn: Callable[[bytes], bytes] = (
        decompress_obj.decompress  # type: ignore
        if options['use_compression'] else identity
    )
    hmac = HMAC(key, SHA256(), default_backend())
    writer = output_file.writer(); next(writer)
    for encrypted_data in input_file.reader():
        if options['use_encryption']:
            hmac.update(encrypted_data)
        decrypted_data += decrypt_fn(encrypted_data)
        logger.debug2(f'decrypt_fn returned {len(decrypted_data)} bytes')

        block = unzip_fn(decrypted_data)
        logger.debug2(f'unzip_fn returned {len(block)} bytes')
        writer.send(block)
        decrypted_data = decompress_obj.unused_data

    # Decompress and write out the last block
    if decrypted_data:
        block = unzip_fn(decrypted_data)
        logger.debug2(f'unzip_fn returned {len(block)} bytes')
        writer.send(block)

    try:
        if options['use_encryption']:
            hmac.verify(signature)
    except InvalidSignature as e:
        raise BackupCorruptedError("The file's signature did not match the data") from e
Example #23
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 #24
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 #25
0
def MydecryptMAC(c, tag, iv, enckey, HMACKey):
    if len(HMACKey) != KEY_BYTES:
        sys.stderr.write('Error: Key length must be 32 bytes.')
    else:
        # generates new tag
        tagPrime = HMAC(HMACKey, hashes.SHA256(), backend=default_backend())
        tagPrime.update(c)

        # verifies tags match
        # errors if false
        tagPrime.verify(tag)

        # decrypts message after tag verification
        message = mydecrypt(c, iv, enckey)

        print('... Finished mydecrypt (mac)')
        return message
Example #26
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 #27
0
    def decrypt(self, ct, iv, mac):
        ct, iv, mac = bytes(ct, "ascii"), bytes(iv,
                                                "ascii"), bytes(mac, "ascii")

        mac = b64decode(mac)

        h = HMAC(self.macKey, SHA256(), default_backend())
        h.update(ct + iv)
        h.verify(mac)  #verify MAC

        ct, iv = b64decode(ct), b64decode(iv)

        decryptor = Cipher(self.cipherAlg, self.mode(iv),
                           default_backend()).decryptor()
        message = decryptor.update(ct) + decryptor.finalize()  #decrypt

        return message
Example #28
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 #29
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 #30
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 #31
0
def test_compress_and_encrypt_no_compression(caplog, mock_open_streams):
    orig, new, _ = mock_open_streams
    signature = compress_and_encrypt(
        orig,
        new,
        TMP_KEYPAIR,
        dict(use_compression=False, use_encryption=True),
    )

    cipher = Cipher(AES(TMP_KEY), CTR(TMP_NONCE),
                    backend=default_backend()).decryptor()
    hmac = HMAC(TMP_KEY, SHA256(), default_backend())
    decrypted = cipher.update(new._fd.getvalue())
    hmac.update(new._fd.getvalue())
    assert decrypted == orig._fd.getvalue()
    assert count_matching_log_lines('read 2 bytes from /orig', caplog) == 4
    assert count_matching_log_lines('wrote 2 bytes to /new', caplog) == 4
    hmac.verify(signature)
Example #32
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 #33
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 #34
0
    def decrypt(self, ct, nonce, mac):
        ct, nonce, mac = bytes(ct,
                               "ascii"), bytes(nonce,
                                               "ascii"), bytes(mac, "ascii")

        mac = b64decode(mac)

        h = HMAC(self.macKey, SHA256(), default_backend())
        h.update(ct + nonce)
        h.verify(mac)  #verify MAC

        ct, nonce = b64decode(ct), b64decode(nonce)

        decryptor = Cipher(self.cipherAlg(self.key, nonce), None,
                           default_backend()).decryptor()
        message = decryptor.update(ct) + decryptor.finalize()  #decrypt

        return message
Example #35
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 #36
0
    def dec(self, byts):
        '''
        Decode an envelope dict and decrypt the given bytes.

        Args:
            byts (bytes): Bytes to decrypt.

        Returns:
            bytes: Decrypted message.
        '''

        envl = s_msgpack.un(byts)

        macr = HMAC(self.skey, hashes.SHA256(), backend=self.bend)

        iv = envl.get('iv', b'')
        hmac = envl.get('hmac', b'')
        data = envl.get('data', b'')

        macr.update(iv + data)

        try:
            macr.verify(hmac)
        except InvalidSignature as e:
            logger.warning('Error in macr.verify: [%s]', str(e))
            return None

        mode = modes.CBC(iv)
        algo = algorithms.AES(self.ekey)

        decr = Cipher(algo, mode, self.bend).decryptor()

        # decrypt the remaining bytes
        byts = decr.update(data)
        byts += decr.finalize()

        # unpad the decrypted bytes
        padr = padding.PKCS7(self.bsize).unpadder()

        byts = padr.update(byts)
        byts += padr.finalize()

        return byts
Example #37
0
    def _decrypt_cryptography(b_ciphertext, b_crypted_hmac, b_key1, b_key2,
                              b_iv):
        # 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:
            return None

        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 #38
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 #39
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 #40
0
def opdata1_decrypt_item(data, key, hmac_key, aes_size=C_AES_SIZE, ignore_hmac=False):
    key_size = KEY_SIZE[aes_size]
    assert len(key) == key_size
    assert len(data) >= OPDATA1_MINIMUM_SIZE
    plaintext_length, iv, cryptext, expected_hmac, hmac_d_data = opdata1_unpack(data)
    if not ignore_hmac:
        verifier = HMAC(hmac_key, SHA256(), backend=_backend)
        verifier.update(hmac_d_data)
        if len(verifier.copy().finalize()) != len(expected_hmac):
            raise ValueError("Got unexpected HMAC length (expected %d bytes, got %d bytes)" % (
                len(expected_hmac),
                len(got_hmac)
            ))
        try:
            verifier.verify(expected_hmac)
        except InvalidSignature:
            raise ValueError("HMAC did not match for opdata1 record")
    aes = Cipher(algorithms.AES(key), modes.CBC(iv), backend=_backend)
    decryptor = aes.decryptor()
    decrypted = decryptor.update(cryptext) + decryptor.finalize()
    unpadded = padding.ab_unpad(decrypted, plaintext_length)
    return unpadded
Example #41
0
    def decrypt(self, token):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes")

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

        hmac = token[-32:]
        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(token[:-32])
        try:
            h.verify(hmac)
        except InvalidSignature:
            raise InvalidToken

        iv = token[1:17]
        ciphertext = token[17:-32]
        decryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv),
                           self.backend).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken

        plaintext = self.remove_padding(plaintext_padded,
                                        algorithms.AES.block_size)

        try:
            data_id, = struct.unpack(config.FORMAT_CHAR, plaintext[:8])
        except struct.error:
            raise InvalidToken

        if data_id == config.DUMMY_ID:
            raise DummyFileFound

        data = plaintext[8:]
        return data_id, data
Example #42
0
    def decrypt(self, token):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes")

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

        hmac = token[-32:]
        h = HMAC(self.mac_key, hashes.SHA256(), backend=self.backend)
        h.update(token[:-32])
        try:
            h.verify(hmac)
        except InvalidSignature:
            raise InvalidToken

        iv = token[1:17]
        ciphertext = token[17:-32]
        decryptor = Cipher(algorithms.AES(self.aes_key), modes.CBC(iv), self.backend).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken

        plaintext = self.remove_padding(plaintext_padded, algorithms.AES.block_size)

        try:
            data_id, = struct.unpack(config.FORMAT_CHAR, plaintext[:8])
        except struct.error:
            raise InvalidToken

        if data_id == config.DUMMY_ID:
            raise DummyFileFound

        data = plaintext[8:]
        return data_id, data
Example #43
0
    def decrypt(self, token, ttl=None, adata = ""):

        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")

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

        if data == 0x82 or six.indexbytes(data, 0) == 0x82:
            # print("82 version\n")
            try:
                salt = data[1:17]
            except ValueError:
                raise InvalidToken

            # print("salt == " + str(len(salt)), salt)
            # is this producing same signing and encrypt key? YES!
            signing_key, encryption_key = self.gen_encrypt_key(salt, self._password)
            # print("signing_key == " + str(len(signing_key)), signing_key)
            # print("encryption_key == " + str(len(encryption_key)), encryption_key)
            ############ VERIFYING adata
            # print("data = " + str(len(data)), data)
            h = HMAC(signing_key, hashes.SHA256(), backend=self._backend)
            basic_parts = data[:-32]
            basic_adata = basic_parts + base64.urlsafe_b64decode(base64.urlsafe_b64encode(adata))
            # print("==================", base64.urlsafe_b64decode(base64.urlsafe_b64encode(adata)))
            h.update(basic_adata)
            # print("basic_parts_len = " + str(len(basic_parts)), basic_parts)

            # print("basic_adata = " + str(len(basic_adata)), basic_adata)
            # print("adata = " , len(adata), adata)
            try:
                h.verify(data[-32:])
            except InvalidSignature:
                raise InvalidToken

            ################ signature stuff from fernet.py
            # h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
            # h.update(data[:-32]) # get everything from data except for last 32 bytes
            # # print(h.update(data[:-32]))
            # try:
            #     # verifying signature with the last 32 bytes
            #     h.verify(data[-32:])
            # except InvalidSignature:
            #     raise InvalidToken
            ################ END-OF signature stuff from fernet.py
            # TODO: get associated data
            # check for correct associated data

            # iv = data[9:25]

            # find out associated data in data
            # try satement, if adata_to_get = adata
            ciphertext = data[17:-32]
            decryptor = Cipher(
                algorithms.AES(encryption_key), modes.CBC("0"*16), 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

        else:
            raise InvalidToken
Example #44
0
    def decrypt(self, token, ttl=None, adata=""):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")
        # print("token = ", token)

        try:
            data = base64.urlsafe_b64decode(token)
        except (TypeError, binascii.Error):
            raise InvalidToken
        # print("data = ", data)
        if not data or six.indexbytes(data, 0) == 0x80:
            print("80 version\n")
            # TODO: if 80:
            try:
                msg = self._f.decrypt(token, ttl)
                return msg
            except:
                raise InvalidToken

        elif not data or six.indexbytes(data, 0) == 0x81:
            # print("81 version\n")

            ############ VERIFYING adata
            # print("data = " + str(len(data)), data)
            h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
            basic_parts = data[:-32]
            basic_adata = basic_parts + bytes(adata)
            # print("==================", base64.urlsafe_b64decode(base64.urlsafe_b64encode(adata)))
            h.update(basic_adata)
            # print("basic_parts_len = " + str(len(basic_parts)), basic_parts)

            # print("basic_adata = " + str(len(basic_adata)), basic_adata)
            # print("adata = " , len(adata), adata)
            try:
                h.verify(data[-32:])
            except InvalidSignature:
                raise InvalidToken

            ################ signature stuff from fernet.py
            # h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
            # h.update(data[:-32]) # get everything from data except for last 32 bytes
            # # print(h.update(data[:-32]))
            # try:
            #     # verifying signature with the last 32 bytes
            #     h.verify(data[-32:])
            # except InvalidSignature:
            #     raise InvalidToken
            ################ END-OF signature stuff from fernet.py

            # iv = data[9:25]
            iv = data[1:17]
            # print("iv == " + str(len(iv)), iv)
            # find out associated data in data
            # try satement, if adata_to_get = adata
            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

        else:
            raise InvalidToken