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 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
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
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 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.
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 checkHMAC(self, fp, segments_start, segments_end, fileHMAC): '''Check the file's integrity''' filehash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend) filehash.update(self.FileMACPrefix) for segmentIndex, startpos, datalen in self.segment_ranges(segments_start, segments_end): print(" Segment %d" % (segmentIndex)) fp.seek(startpos) segmentIV = fp.read(self.SegIVLen) segmentMAC = fp.read(self.SegMACLen) # Verify the segment's own MAC against the segment data segmenthash = HMAC(self.hmackey, primitives.hashes.SHA256(), backend) segmenthash.update(segmentIV) segmenthash.update(struct.pack('>I', segmentIndex)) segmenthash.update(fp.read(datalen)) # The cryptography module doesn't handle truncated HMACs directly computed = segmenthash.finalize() assert primitives.constant_time.bytes_eq(computed[:self.SegMACLen], segmentMAC) # Add the segment's MAC to the file-MAC context filehash.update(segmentMAC) # Finally, verify the file MAC print(" File hash") filehash.verify(fileHMAC) # Raises on mismatch.
def _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
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
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)
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
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)
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)
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
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
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)
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
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
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
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")
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
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
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
def hmac_verify(key, data, hash_alg, backend, sig = None): h = HMAC( key, hash_alg, backend=backend ) h.update(data) return h.verify(sig)
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
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
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)
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)
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
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
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
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
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
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
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
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
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
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