def _decrypt_data(self, data): assert self._encryption_key from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from binascii import a2b_base64 key = self._encryption_key encoded_message = a2b_base64(data) version = encoded_message[0:1] tag = encoded_message[1:17] initialization_vector = encoded_message[17:29] encrypted_message = encoded_message[29:] if version != b"1": raise Exception("Invalid Version") cipher = Cipher(algorithms.AES(key), modes.GCM(initialization_vector, tag), backend=default_backend()) decryptor = cipher.decryptor() decrypted = decryptor.update(encrypted_message) + decryptor.finalize() decrypted = decrypted.decode() return(decrypted)
def _aes_decrypt(key, iv, tag, data, aead=''): backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend=backend) decryptor = cipher.decryptor() if aead: decryptor.authenticate_additional_data(aead) return decryptor.update(data) + decryptor.finalize()
def decrypt(self, k, a, iv, e, t): """ Decrypt according to the selected encryption and hashing functions. :param k: Encryption key (optional) :param a: Additional Authenticated Data :param iv: Initialization Vector :param e: Ciphertext :param t: Authentication Tag Returns plaintext or raises an error """ hkey = k[:self.keysize] dkey = k[self.keysize:] # verify mac if not constant_time.bytes_eq(t, self._mac(hkey, a, iv, e)): raise InvalidJWEData('Failed to verify MAC') # decrypt cipher = Cipher(algorithms.AES(dkey), modes.CBC(iv), backend=self.backend) decryptor = cipher.decryptor() d = decryptor.update(e) + decryptor.finalize() unpadder = PKCS7(self.blocksize).unpadder() return unpadder.update(d) + unpadder.finalize()
def test_unknown_error_in_cipher_finalize(self): cipher = Cipher(AES(b"\0" * 16), CBC(b"\0" * 16), backend=backend) enc = cipher.encryptor() enc.update(b"\0") backend._lib.ERR_put_error(0, 0, 1, b"test_openssl.py", -1) with pytest.raises(InternalError): enc.finalize()
def _aes_encrypt(key, iv, data, aead=''): backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=backend) encryptor = cipher.encryptor() if aead: encryptor.authenticate_additional_data(aead) return encryptor.update(data) + encryptor.finalize(), encryptor.tag
def unwrap(self, key, ek): rk = self.get_key(key, 'decrypt') # Implement RFC 3394 Key Unwrap - 2.2.3 # TODO: Use cryptography once issue #1733 is resolved iv = 'a6a6a6a6a6a6a6a6' Aiv = unhexlify(iv) R = [ek[i:i+8] for i in range(0, len(ek), 8)] A = R.pop(0) n = len(R) for j in range(5, -1, -1): for i in range(n - 1, -1, -1): AtR = _encode_int((_decode_int(A) ^ ((n*j)+i+1)), 64) + R[i] d = Cipher(algorithms.AES(rk), modes.ECB(), backend=self.backend).decryptor() B = d.update(AtR) + d.finalize() A = B[:8] R[i] = B[-8:] if A != Aiv: raise InvalidJWEData('Decryption Failed') cek = b''.join(R) return cek
def encrypt(self, k, a, m): """ Encrypt according to the selected encryption and hashing functions. :param k: Encryption key (optional) :param a: Additional Authentication Data :param m: Plaintext Returns a dictionary with the computed data. """ hkey = k[:self.keysize] ekey = k[self.keysize:] # encrypt iv = os.urandom(self.blocksize // 8) cipher = Cipher(algorithms.AES(ekey), modes.CBC(iv), backend=self.backend) encryptor = cipher.encryptor() padder = PKCS7(self.blocksize).padder() padded_data = padder.update(m) + padder.finalize() e = encryptor.update(padded_data) + encryptor.finalize() # mac t = self._mac(hkey, a, iv, e) return (iv, e, t)
def aead_exception_test(backend, cipher_factory, mode_factory): cipher = Cipher( cipher_factory(binascii.unhexlify(b"0" * 32)), mode_factory(binascii.unhexlify(b"0" * 24)), backend ) encryptor = cipher.encryptor() encryptor.update(b"a" * 16) with pytest.raises(NotYetFinalized): encryptor.tag with pytest.raises(AlreadyUpdated): encryptor.authenticate_additional_data(b"b" * 16) encryptor.finalize() with pytest.raises(AlreadyFinalized): encryptor.authenticate_additional_data(b"b" * 16) with pytest.raises(AlreadyFinalized): encryptor.update(b"b" * 16) with pytest.raises(AlreadyFinalized): encryptor.finalize() cipher = Cipher( cipher_factory(binascii.unhexlify(b"0" * 32)), mode_factory(binascii.unhexlify(b"0" * 24), b"0" * 16), backend ) decryptor = cipher.decryptor() decryptor.update(b"a" * 16) with pytest.raises(AttributeError): decryptor.tag
def test_creates_decryptor(self, backend): cipher = Cipher( algorithms.AES(binascii.unhexlify(b"0" * 32)), modes.CBC(binascii.unhexlify(b"0" * 32)), backend ) assert isinstance(cipher.decryptor(), base.CipherContext)
def encrypt(keyBits, plainData, params): """ Encrypt the plainData using the keyBits according the encrypt params. :param Blob keyBits: The key value. :param Blob plainData: The data to encrypt. :param EncryptParams params: This encrypts according to params.getAlgorithmType() and other params as needed such as params.getInitialVector(). :return: The encrypted data. :rtype: Blob """ # For the cryptography package, we have to do the padding. padLength = 16 - (plainData.size() % 16) if sys.version_info[0] <= 2: pad = chr(padLength) * padLength else: pad = bytes([padLength]) * padLength if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.ECB(), backend = default_backend()) elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()), backend = default_backend()) else: raise RuntimeError("unsupported encryption mode") encryptor = cipher.encryptor() return Blob( encryptor.update(plainData.toBytes() + pad) + encryptor.finalize(), False)
def decrypt(keyBits, encryptedData, params): """ Decrypt the encryptedData using the keyBits according the encrypt params. :param Blob keyBits: The key value. :param Blob encryptedData: The data to decrypt. :param EncryptParams params: This decrypts according to params.getAlgorithmType() and other params as needed such as params.getInitialVector(). :return: The decrypted data. :rtype: Blob """ if params.getAlgorithmType() == EncryptAlgorithmType.AesEcb: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.ECB(), backend = default_backend()) elif params.getAlgorithmType() == EncryptAlgorithmType.AesCbc: cipher = Cipher(algorithms.AES( keyBits.toBytes()), modes.CBC(params.getInitialVector().toBytes()), backend = default_backend()) else: raise RuntimeError("unsupported encryption mode") # For the cryptography package, we have to remove the padding. decryptor = cipher.decryptor() resultWithPad = decryptor.update(encryptedData.toBytes()) + decryptor.finalize() if sys.version_info[0] <= 2: padLength = ord(resultWithPad[-1]) else: padLength = resultWithPad[-1] return Blob(resultWithPad[:-padLength], False)
def test_ciphers(self): backend = MultiBackend([ DummyHashBackend([]), DummyCipherBackend([ (algorithms.AES, modes.CBC), ]) ]) assert backend.cipher_supported( algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16) ) cipher = Cipher( algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16), backend=backend ) cipher.encryptor() cipher.decryptor() cipher = Cipher( algorithms.Camellia(b"\x00" * 16), modes.CBC(b"\x00" * 16), backend=backend ) with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER): cipher.encryptor() with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER): cipher.decryptor()
def decrypt(self, data, ttl=None): """ :type data: bytes :type ttl: int :rtype: bytes """ data = self._signer.unsign(data, ttl) iv = data[:16] ciphertext = data[16:] 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 # Remove padding 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, data, associated_data=b""): decoded_data = base64.urlsafe_b64decode(data) mac = decoded_data[-16:] iv = decoded_data[0:16] cipher_text = decoded_data[16:-16] associated_data_length = struct.pack(">Q", len(associated_data) * 8) h = hmac.HMAC(self.mac_key, hashes.SHA256(), self.backend) h.update(associated_data) h.update(iv) h.update(cipher_text) h.update(associated_data_length) if not constant_time.bytes_eq(mac, h.finalize()[:16]): raise ValueError("data provided has an invalid signature.") cipher = Cipher( algorithms.AES(self.encryption_key), modes.CBC(iv), self.backend ) decryptor = cipher.decryptor() plain_text = decryptor.update(cipher_text) + decryptor.finalize() unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() unpadded_data = unpadder.update(plain_text) + unpadder.finalize() return unpadded_data
def _decrypt_aesgcm(key, nonce, ciphertext_tag, associated_data): """ Decrypts a ciphertext with associated data with AES GCM. Args: key: encryption key nonce: nonce for encryption ciphertext_tag: ciphertext with appended tag to decrypt associated_data: additional authenticated associated data (the AD in AEAD) Returns: decrypted plaintext """ if len(ciphertext_tag) < MAC_BYTES: raise NoiseError('Truncated ciphertext (length < authentication tag length).') algo = algorithms.AES(key) assert len(nonce) == 12, 'Expected 96 bit nonce for AES-GCM' ciphertext, tag = ciphertext_tag[:-MAC_BYTES], ciphertext_tag[-MAC_BYTES:] mode = modes.GCM(nonce, tag) decryptor = Cipher(algo, mode, backend).decryptor() decryptor.authenticate_additional_data(associated_data) try: return decryptor.update(ciphertext) + decryptor.finalize() except InvalidTag as invalid_tag: raise NoiseError('GMAC failure') from invalid_tag
def decrypt(key, associated_data, iv, ciphertext, tag): # Construct a Cipher object, with the key, iv, and additionally the # GCM tag used for authenticating the message. # OK.. all the objects passed in to this function are of type bytearray, but, it turns # out that the Cipher suite needs strings, despite saying in the documentation that it needs # bytes. Consequently all the parameter objects had to be converted to strings, hence the str() # around each one. # The moral of this story is strong typing is good. try: decryptor = Cipher( algorithms.AES(str(key)), modes.GCM(str(iv), str(tag)), backend=default_backend() ).decryptor() # We put associated_data back in or the tag will fail to verify # when we finalize the decryptor. decryptor.authenticate_additional_data(str(associated_data)) # Decryption gets us the authenticated plaintext. # If the tag does not match an InvalidTag exception will be raised. ret = decryptor.update(str(ciphertext)) + decryptor.finalize() except Exception as e: print(" Failed to de-crypt Measurement with exception: {}: {}".format(e.__class__.__name__, e)) ret = None return ret
class CipherShim: def __init__(self, cipher, mode, block_size, key, iv, initial_bytes): if mode: mode = mode(iv) self._cipher = Cipher(cipher(key), mode, default_backend()) self._initial_bytes = initial_bytes self._encryptor = None self._decryptor = None self.block_size = block_size def encrypt(self, data): if not self._encryptor: self._encryptor = self._cipher.encryptor() if self._initial_bytes: self._encryptor.update(self._initial_bytes * b'\0') return self._encryptor.update(data) def decrypt(self, data): if not self._decryptor: self._decryptor = self._cipher.decryptor() if self._initial_bytes: self._decryptor.update(self._initial_bytes * b'\0') return self._decryptor.update(data)
def test_ciphers(self): backend = MultiBackend([ DummyHashBackend([]), DummyCipherBackend([ (algorithms.AES, modes.CBC), ]) ]) assert backend.cipher_supported( algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16) ) cipher = Cipher( algorithms.AES(b"\x00" * 16), modes.CBC(b"\x00" * 16), backend=backend ) cipher.encryptor() cipher.decryptor() cipher = Cipher( algorithms.Camellia(b"\x00" * 16), modes.CBC(b"\x00" * 16), backend=backend ) with pytest.raises(UnsupportedCipher): cipher.encryptor() with pytest.raises(UnsupportedCipher): cipher.decryptor()
def decrypt(packed_encrypted_data, key, mac_key='', backend=BACKEND): """ Decrypts packed encrypted data as returned by encrypt with the same key. If extra data is present, returns plaintext, extra_data. If not, returns plaintext. Raises InvalidTag on authentication failure. """ header, ciphertext, iv, tag, extra_data = load_data(packed_encrypted_data) algorithm, mode, authentication_algorithm = header.split('_', 2) if algorithm.lower() in hashlib.algorithms_guaranteed: return cryptographyless.decrypt(packed_encrypted_data, key, mac_key, backend) mode_args = (iv, tag) if mode in AEAD_MODES else (iv, ) decryptor = Cipher(getattr(algorithms, algorithm)(key), getattr(modes, mode)(*mode_args), backend=BACKEND).decryptor() if mode in AEAD_MODES: decryptor.authenticate_additional_data(extra_data) else: if not mac_key: raise ValueError("mac_key not supplied for {} mode".format(header)) if not verify_mac(mac_key, save_data(tag, header + ciphertext + iv + extra_data), authentication_algorithm): raise InvalidTag("Failed to authenticate data") plaintext = decryptor.update(ciphertext) + decryptor.finalize() if extra_data: return (plaintext, extra_data) else: return plaintext
def encryptData(self, dataS, iv): self.data = str(dataS).encode() self.iv = iv cipher = Cipher(algorithms.AES(self.key), modes.CTR(self.iv), backend=self.backend) encryptor = cipher.encryptor() self.encryptedData = encryptor.update(self.data) + encryptor.finalize() return self.encryptedData
def encrypt(encryption_key, iv, data): """Encrypt the payload.""" padder = padding.PKCS7(algorithms.AES.block_size).padder() data = padder.update(data.encode()) + padder.finalize() encryptor = Cipher(algorithms.AES(encryption_key), modes.CBC(iv), default_backend()).encryptor() return base64.urlsafe_b64encode(encryptor.update(data) + encryptor.finalize())
def cryptography_symmetric_encrypt(encrypt_key, plaintext): """ Encrypt the provided plaintext using AES encryption. NOTE 1: This function return a string which is fully compatible with Keyczar.Encrypt() method. NOTE 2: This function is loosely based on keyczar AESKey.Encrypt() (Apache 2.0 license). The final encrypted string value consists of: [message bytes][HMAC signature bytes for the message] where message consists of [keyczar header plaintext][IV bytes][ciphertext bytes] NOTE: Header itself is unused, but it's added so the format is compatible with keyczar format. """ assert isinstance(encrypt_key, AESKey), 'encrypt_key needs to be AESKey class instance' assert isinstance(plaintext, (six.text_type, six.string_types, six.binary_type)), \ 'plaintext needs to either be a string/unicode or bytes' aes_key_bytes = encrypt_key.aes_key_bytes hmac_key_bytes = encrypt_key.hmac_key_bytes assert isinstance(aes_key_bytes, six.binary_type) assert isinstance(hmac_key_bytes, six.binary_type) if isinstance(plaintext, (six.text_type, six.string_types)): # Convert data to bytes data = plaintext.encode('utf-8') else: data = plaintext # Pad data data = pkcs5_pad(data) # Generate IV iv_bytes = os.urandom(KEYCZAR_AES_BLOCK_SIZE) backend = default_backend() cipher = Cipher(algorithms.AES(aes_key_bytes), modes.CBC(iv_bytes), backend=backend) encryptor = cipher.encryptor() # NOTE: We don't care about actual Keyczar header value, we only care about the length (5 # bytes) so we simply add 5 0's header_bytes = b'00000' ciphertext_bytes = encryptor.update(data) + encryptor.finalize() msg_bytes = header_bytes + iv_bytes + ciphertext_bytes # Generate HMAC signature for the message (header + IV + ciphertext) h = hmac.HMAC(hmac_key_bytes, hashes.SHA1(), backend=backend) h.update(msg_bytes) sig_bytes = h.finalize() result = msg_bytes + sig_bytes # Convert resulting byte string to hex notation ASCII string result = binascii.hexlify(result).upper() return result
def CBC_MAC(key, iv, padded): cipher = Cipher(algorithm = algorithms.AES(key), mode = modes.CBC(iv), backend=default_backend()) enc = cipher.encryptor() ciphertext = enc.update(padded) + enc.finalize() mac = ciphertext[-16:] return mac
def decrypt_payload(self, key, dest_path, chunksize=CHUNKSIZE): with open(self.enc_payload, 'rb') as infile: iv = infile.read(16) backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) decryptor = cipher.decryptor() origsize = 0 with open(self.payload, 'wb') as outfile: while True: chunk = infile.read(chunksize) if len(chunk) == 0: break plaintext = decryptor.update(chunk) if origsize: outfile.write(plaintext) else: origsize, pad = struct.unpack('<QQ', plaintext[0:16]) outfile.write(plaintext[16:]) outfile.write(decryptor.finalize()) outfile.truncate(origsize) archive = tarfile.open(self.payload) archive.extractall(dest_path) archive.close()
def _decrypt(self, b, strip_padding=True): """Decrypt a byte string. Uses the AES 256-bit symmetric key cypher. Args: b: the byte string to decrypt. strip_padding: whether to remove the padding (padding is required by AES2 to make the encrypted data an exact multiple of 16 bytes in length). Returns: The decrypted data as a byte string. """ from cryptography.hazmat.primitives.ciphers \ import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend backend = default_backend() cypher = Cipher( algorithms.AES(self.__key), modes.CBC(self.__iv), backend=backend) decryptor = cypher.decryptor() result = decryptor.update(b) + decryptor.finalize() if strip_padding: result = result[:-result[-1]] return result
class CommutativeCipher: """ Encryption and decryption using a commutative cipher. """ def __init__(self): key = os.urandom(32) iv = os.urandom(16) self.cipher = Cipher(algorithms.AES(key), modes.OFB(iv), backend=default_backend()) def encrypt(self, plaintext, base64=False): """ Encrypts a plaintext message and returns base 64 encoded ciphertext. If base64 is specified, decodes from base64 first. """ plaintext = plaintext.encode(ENCODING) if base64: plaintext = decodebytes(plaintext) encryptor = self.cipher.encryptor() ciphertext = encryptor.update(plaintext) + encryptor.finalize() return encodebytes(ciphertext).decode(ENCODING) def decrypt(self, ciphertext, base64=False): """ Decrypts base 64 encoded ciphertext and returns the plaintext message. If base64 is specified, provides result base64 encoded. """ ciphertext = decodebytes(ciphertext.encode(ENCODING)) decryptor = self.cipher.decryptor() plaintext = decryptor.update(ciphertext) + decryptor.finalize() if base64: plaintext = encodebytes(plaintext) return plaintext.decode(ENCODING)
def encrypt_payload(self, key, source_path, chunksize=CHUNKSIZE): archive = tarfile.open(self.payload, mode='w:gz') archive.add(source_path, arcname=os.path.basename(source_path)) archive.close() iv = b''.join(int2byte(random.randint(0, 0xFF)) for i in range(16)) backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() origsize = os.path.getsize(self.payload) with open(self.payload, 'rb') as infile: with open(self.enc_payload, 'wb') as outfile: outfile.write(iv) # store the file size with the encrypted data outfile.write(encryptor.update(struct.pack('<QQ', origsize, 0))) while True: chunk = infile.read(chunksize) if len(chunk) == 0: break elif len(chunk) % 16 != 0: chunk += b' ' * (16 - len(chunk) % 16) outfile.write(encryptor.update(chunk)) outfile.write(encryptor.finalize())
def decrypt_blob(storage, blob_id, key, offset=0, length=None): """Decrypt the content of a blob through a generator.""" modulo = offset % 16 # Compute a file offset, might be lower than the real offset file_offset = offset - modulo if offset else 0 end = offset + length if length else None algorithm = algorithms.AES(key) counter = counter_for_offset(offset) cipher = Cipher(algorithm=algorithm, mode=counter, backend=default_backend()) decryptor = cipher.decryptor() chunks_generator = storage.read_in_chunks(blob_id, offset=file_offset, chunk_size=10) for i, enc_chunk in chunks_generator: chunk = decryptor.update(enc_chunk) if end is not None: here = offset - modulo + i*10 if end <= here + 10: chunk = chunk[:end - here] yield chunk break if i == 0: yield chunk[modulo:] else: yield chunk yield decryptor.finalize()
def decrypt(self, ciphertext): ''' The decrypt constructor takes the ciphertext string, sends it to the postProcess class to be chunked. The blocks are then decrypted and unpadded using the python cryptography library. Returns a ciphertext string. ''' # Send the ciphertext string to be chunked ciphertext = self.postProcess(ciphertext) # Initilize the python cryptography ECB mode backend = default_backend() cipher = Cipher(algorithms.AES(self.key), modes.ECB(), backend = backend) decryptor = cipher.decryptor() # Loop through decrypt the ciphertext and then unpad. plaintextList = [] if (len(ciphertext) == 1): plaintext = decryptor.update(ciphertext[0]) unPaddedPt = self.unPad(plaintext) return unPaddedPt else: for i in range(0, len(ciphertext)): plaintext = decryptor.update(ciphertext[i]) plaintextList.append(plaintext) paddedElement = self.unPad(plaintextList.pop(-1)) plaintextList.append(paddedElement) return ''.join(plaintextList)
def decrypt(self): pad = self.enc_pad(self.enckey, self.pad_iv) aes = Cipher(AES(self.enckey), CTR(self.iv), default_backend()).decryptor() self.fwd = pad + aes.update(self.onion[:self.fwd_end]) self.msg = aes.update(self.onion[self.fwd_end:self.msg_end])
def _encrypt(key_data, derived_key_information): """ Encrypt 'key_data' using the Advanced Encryption Standard (AES-256) algorithm. 'derived_key_information' should contain a key strengthened by PBKDF2. The key size is 256 bits and AES's mode of operation is set to CTR (CounTeR Mode). The HMAC of the ciphertext is generated to ensure the ciphertext has not been modified. 'key_data' is the JSON string representation of the key. In the case of RSA keys, this format would be 'securesystemslib.formats.RSAKEY_SCHEMA': {'keytype': 'rsa', 'keyval': {'public': '-----BEGIN RSA PUBLIC KEY----- ...', 'private': '-----BEGIN RSA PRIVATE KEY----- ...'}} 'derived_key_information' is a dictionary of the form: {'salt': '...', 'derived_key': '...', 'iterations': '...'} 'securesystemslib.exceptions.CryptoError' raised if the encryption fails. """ # Generate a random Initialization Vector (IV). Follow the provably secure # encrypt-then-MAC approach, which affords the ability to verify ciphertext # without needing to decrypt it and preventing an attacker from feeding the # block cipher malicious data. Modes like GCM provide both encryption and # authentication, whereas CTR only provides encryption. # Generate a random 128-bit IV. Random bits of data is needed for salts and # initialization vectors suitable for the encryption algorithms used in # 'pyca_crypto_keys.py'. iv = os.urandom(16) # Construct an AES-CTR Cipher object with the given key and a randomly # generated IV. symmetric_key = derived_key_information['derived_key'] encryptor = Cipher(algorithms.AES(symmetric_key), modes.CTR(iv), backend=default_backend()).encryptor() # Encrypt the plaintext and get the associated ciphertext. # Do we need to check for any exceptions? ciphertext = encryptor.update( key_data.encode('utf-8')) + encryptor.finalize() # Generate the hmac of the ciphertext to ensure it has not been modified. # The decryption routine may verify a ciphertext without having to perform # a decryption operation. symmetric_key = derived_key_information['derived_key'] salt = derived_key_information['salt'] hmac_object = \ cryptography.hazmat.primitives.hmac.HMAC(symmetric_key, hashes.SHA256(), backend=default_backend()) hmac_object.update(ciphertext) hmac_value = binascii.hexlify(hmac_object.finalize()) # Store the number of PBKDF2 iterations used to derive the symmetric key so # that the decryption routine can regenerate the symmetric key successfully. # The PBKDF2 iterations are allowed to vary for the keys loaded and saved. iterations = derived_key_information['iterations'] # Return the salt, iterations, hmac, initialization vector, and ciphertext # as a single string. These five values are delimited by # '_ENCRYPTION_DELIMITER' to make extraction easier. This delimiter is # arbitrarily chosen and should not occur in the hexadecimal representations # of the fields it is separating. return binascii.hexlify(salt).decode() + _ENCRYPTION_DELIMITER + \ str(iterations) + _ENCRYPTION_DELIMITER + \ hmac_value.decode() + _ENCRYPTION_DELIMITER + \ binascii.hexlify(iv).decode() + _ENCRYPTION_DELIMITER + \ binascii.hexlify(ciphertext).decode()
def __init__(self, key, counter=0): self._cipher = Cipher(algorithms.AES(key), modes.CTR(long_to_bytes(counter << 64, 16)), self.__backend__)
def init_secret_key(self): # TODO Add support for private keys. if False: # rsa = PKCS1_v1_5.new(RSA.importKey(self._private_key)) # self.secret_key = rsa.decrypt(self.ei.encrypted_key_value, None) # Presumably the following is correct. # self.verifier_hash_input = rsa.decrypt( # self.ei.verifier_hash_input, None # ) # self.verifier_hash_value = rsa.decrypt( # self.ei.verifier_hash_value, None # ) pass if self.password: block_verifier_input = bytearray( [0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79]) block_verifier_value = bytearray( [0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e]) block_encrypted_key = bytearray([ 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6, ]) # AES decrypt the encrypted* values with their pre-defined block # keys and salt in order to get secret key. aes = Cipher(algorithms.AES( self.gen_encryption_key(block_verifier_input)), modes.CBC(self.ei.password_salt), backend=default_backend()).decryptor() self.verifier_hash_input = aes.update( self.ei.verifier_hash_input) + aes.finalize() aes = Cipher(algorithms.AES( self.gen_encryption_key(block_verifier_value)), modes.CBC(self.ei.password_salt), backend=default_backend()).decryptor() self.verifier_hash_value = aes.update( self.ei.verifier_hash_value) + aes.finalize() aes = Cipher(algorithms.AES( self.gen_encryption_key(block_encrypted_key)), modes.CBC(self.ei.password_salt), backend=default_backend()).decryptor() self.secret_key = (aes.update(self.ei.encrypted_key_value) + aes.finalize())
def encriptarserver(keyaes, iv, ctp): #encriptar cipher = Cipher(algorithms.AES(keyaes), modes.CTR(iv), backend=backend) encryptor = cipher.encryptor() ct = encryptor.update(ctp) + encryptor.finalize() return ct
def __init__( self, remote: Node, privkey: datatypes.PrivateKey, connection: PeerConnection, context: BasePeerContext, inbound: bool = False, token: CancelToken = None, listen_port: int = 30303, ) -> None: super().__init__(token) # Any contextual information the peer may need. self.context = context # The `Node` that this peer is connected to self.remote = remote # The private key this peer uses for identification and encryption. self.privkey = privkey # Networking reader and writer objects for communication self.reader = connection.reader self.writer = connection.writer self.base_protocol = P2PProtocol(self) # Flag indicating whether the connection this peer represents was # established from a dial-out or dial-in (True: dial-in, False: # dial-out) # TODO: rename to `dial_in` and have a computed property for `dial_out` self.inbound = inbound self._subscribers = [] # : List[PeerSubscriber] # Uptime tracker for how long the peer has been running. # TODO: this should move to begin within the `_run` method (or maybe as # part of the `BaseService` API) self.start_time = datetime.datetime.now() # A counter of the number of messages this peer has received for each # message type. self.received_msgs = collections.defaultdict( int) # : Dict[protocol.Command, int] # Encryption and Cryptography *stuff* self.egress_mac = connection.egress_mac self.ingress_mac = connection.ingress_mac # FIXME: Insecure Encryption: https://github.com/ethereum/devp2p/issues/32 iv = b"\x00" * 16 aes_secret = connection.aes_secret mac_secret = connection.mac_secret aes_cipher = Cipher(algorithms.AES(aes_secret), modes.CTR(iv), default_backend()) self.aes_enc = aes_cipher.encryptor() self.aes_dec = aes_cipher.decryptor() mac_cipher = Cipher(algorithms.AES(mac_secret), modes.ECB(), default_backend()) self.mac_enc = mac_cipher.encryptor().update # Manages the boot process self.boot_manager = self.get_boot_manager() # this port is not really used on the other side of TCP communication, py-evm had this wrong but it does not matter self.listen_port = listen_port
def test_instantiate_with_non_algorithm(self, backend): algorithm = object() with pytest.raises(TypeError): Cipher(algorithm, mode=None, backend=backend)
def get_badly_encrypted_password(): dangerous = get_password() cipher = Cipher(algorithms.ARC4(key), _, _) encryptor = cipher.encryptor() return encryptor.update(dangerous) + encryptor.finalize()
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding from cryptography.hazmat.backends import default_backend def read_from_file(): f = open("key.txt", "rb") # print(f.read()) return f.read() # Read key bytes from key file ( into variable key ) key = read_from_file() # Setup cipher : AES in CBC mode , w/ a random IV and PKCS #7 padding ( similar to PKCS #5) iv = os.urandom(algorithms.AES.block_size // 8) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), default_backend()) encryptor = cipher.encryptor() padder = padding.PKCS7(algorithms.AES.block_size).padder() # Open input file for reading and output file for writing input_file = open("ex3_input_file.txt", "rb") output_file = open("ex3_output_file.txt", "wb") # Write the contents of iv in the output file output_file.write(iv) print("iv: ", iv) while True: # Cicle to repeat while there is data left on the input file # Read a chunk of the input file to the plaintext variable plaintext = input_file.read()
# NEVER USE ECB is not secure from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import os key = os.urandom(16) # 16 bytes -> 128 bits: AES-128 aesCipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) aesEncryptor = aesCipher.encryptor() aesDecryptor = aesCipher.decryptor()
def create_AES_cipher(shared_secret): cipher = Cipher(algorithms.AES(shared_secret), modes.CFB8(shared_secret), backend=default_backend()) return cipher
def encrypt_file(encryption_material, in_filename, chunk_size=block_size * 4 * 1024, tmp_dir=None): """Encrypts a file in a temporary directory. Args: encryption_material: The encryption material for file. in_filename: The input file's name. chunk_size: The size of read chunks (Default value = block_size * 4 * 1024). tmp_dir: Temporary directory to use, optional (Default value = None). Returns: The encrypted file's location. """ logger = getLogger(__name__) use_openssl_only = os.getenv('SF_USE_OPENSSL_ONLY', 'False') == 'True' decoded_key = base64.standard_b64decode( encryption_material.query_stage_master_key) key_size = len(decoded_key) logger.debug('key_size = %s', key_size) # Generate key for data encryption iv_data = SnowflakeEncryptionUtil.get_secure_random(block_size) file_key = SnowflakeEncryptionUtil.get_secure_random(key_size) if not use_openssl_only: data_cipher = AES.new(key=file_key, mode=AES.MODE_CBC, IV=iv_data) else: backend = default_backend() cipher = Cipher(algorithms.AES(file_key), modes.CBC(iv_data), backend=backend) encryptor = cipher.encryptor() temp_output_fd, temp_output_file = tempfile.mkstemp( text=False, dir=tmp_dir, prefix=os.path.basename(in_filename) + "#") padded = False logger.debug('unencrypted file: %s, temp file: %s, tmp_dir: %s', in_filename, temp_output_file, tmp_dir) with open(in_filename, 'rb') as infile: with os.fdopen(temp_output_fd, 'wb') as outfile: while True: chunk = infile.read(chunk_size) if len(chunk) == 0: break elif len(chunk) % block_size != 0: chunk = PKCS5_PAD(chunk, block_size) padded = True if not use_openssl_only: outfile.write(data_cipher.encrypt(chunk)) else: outfile.write(encryptor.update(chunk)) if not padded: if not use_openssl_only: outfile.write(data_cipher.encrypt( block_size * chr(block_size).encode(UTF8))) else: outfile.write(encryptor.update( block_size * chr(block_size).encode(UTF8))) if use_openssl_only: outfile.write(encryptor.finalize()) # encrypt key with QRMK if not use_openssl_only: key_cipher = AES.new(key=decoded_key, mode=AES.MODE_ECB) enc_kek = key_cipher.encrypt(PKCS5_PAD(file_key, block_size)) else: cipher = Cipher(algorithms.AES(decoded_key), modes.ECB(), backend=backend) encryptor = cipher.encryptor() enc_kek = encryptor.update(PKCS5_PAD(file_key, block_size)) + encryptor.finalize() mat_desc = MaterialDescriptor( smk_id=encryption_material.smk_id, query_id=encryption_material.query_id, key_size=key_size * 8) metadata = EncryptionMetadata( key=base64.b64encode(enc_kek).decode('utf-8'), iv=base64.b64encode(iv_data).decode('utf-8'), matdesc=matdesc_to_unicode(mat_desc), ) return metadata, temp_output_file
def _parse_signing_key_data(self, data, password): from paramiko.transport import Transport # We may eventually want this to be usable for other key types, as # OpenSSH moves to it, but for now this is just for Ed25519 keys. # This format is described here: # https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key # The description isn't totally complete, and I had to refer to the # source for a full implementation. message = Message(data) if message.get_bytes(len(OPENSSH_AUTH_MAGIC)) != OPENSSH_AUTH_MAGIC: raise SSHException("Invalid key") ciphername = message.get_text() kdfname = message.get_text() kdfoptions = message.get_binary() num_keys = message.get_int() if kdfname == "none": # kdfname of "none" must have an empty kdfoptions, the ciphername # must be "none" if kdfoptions or ciphername != "none": raise SSHException("Invalid key") elif kdfname == "bcrypt": if not password: raise PasswordRequiredException( "Private key file is encrypted") kdf = Message(kdfoptions) bcrypt_salt = kdf.get_binary() bcrypt_rounds = kdf.get_int() else: raise SSHException("Invalid key") if ciphername != "none" and ciphername not in Transport._cipher_info: raise SSHException("Invalid key") public_keys = [] for _ in range(num_keys): pubkey = Message(message.get_binary()) if pubkey.get_text() != "ssh-ed25519": raise SSHException("Invalid key") public_keys.append(pubkey.get_binary()) private_ciphertext = message.get_binary() if ciphername == "none": private_data = private_ciphertext else: cipher = Transport._cipher_info[ciphername] key = bcrypt.kdf( password=b(password), salt=bcrypt_salt, desired_key_bytes=cipher["key-size"] + cipher["block-size"], rounds=bcrypt_rounds, # We can't control how many rounds are on disk, so no sense # warning about it. ignore_few_rounds=True, ) decryptor = Cipher(cipher["class"](key[:cipher["key-size"]]), cipher["mode"](key[cipher["key-size"]:]), backend=default_backend()).decryptor() private_data = (decryptor.update(private_ciphertext) + decryptor.finalize()) message = Message(unpad(private_data)) if message.get_int() != message.get_int(): raise SSHException("Invalid key") signing_keys = [] for i in range(num_keys): if message.get_text() != "ssh-ed25519": raise SSHException("Invalid key") # A copy of the public key, again, ignore. public = message.get_binary() key_data = message.get_binary() # The second half of the key data is yet another copy of the public # key... signing_key = nacl.signing.SigningKey(key_data[:32]) # Verify that all the public keys are the same... assert (signing_key.verify_key.encode() == public == public_keys[i] == key_data[32:]) signing_keys.append(signing_key) # Comment, ignore. message.get_binary() if len(signing_keys) != 1: raise SSHException("Invalid key") return signing_keys[0]
key = b'-8B key-' nonce = Random.new().read(DES.block_size / 2) ctr = Counter.new(DES.block_size * 8 / 2, prefix=nonce) ##Warn: B304 cipher = DES.new(key, DES.MODE_CTR, counter=ctr) plaintext = b'We are no longer the knights who say ni!' msg = nonce + cipher.encrypt(plaintext) key = b'Super secret key' ##Warn: B304 cipher = XOR.new(key) plaintext = b'Encrypt me' msg = cipher.encrypt(plaintext) ##Warn: B304 cipher = Cipher(algorithms.ARC4(key), mode=None, backend=default_backend()) encryptor = cipher.encryptor() ct = encryptor.update(b"a secret message") ##Warn: B304 cipher = Cipher(algorithms.Blowfish(key), mode=None, backend=default_backend()) encryptor = cipher.encryptor() ct = encryptor.update(b"a secret message") ##Warn: B304 cipher = Cipher(algorithms.IDEA(key), mode=None, backend=default_backend()) encryptor = cipher.encryptor() ct = encryptor.update(b"a secret message") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('0.0.0.0', 31137))
def get_cipher(self, initialization_vector): """Generate cipher for AES algorithm.""" cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(initialization_vector), backend=self.backend) return cipher
def _mysql_aes_engine(key): """Create MYSQL AES cipher engine.""" return Cipher(algorithms.AES(key), modes.ECB(), default_backend())
def decrypt_file(metadata, encryption_material, in_filename, chunk_size=block_size * 4 * 1024, tmp_dir=None): """Decrypts a file and stores the output in the temporary directory. Args: metadata: The file's metadata input. encryption_material: The file's encryption material. in_filename: The name of the input file. chunk_size: The size of read chunks (Default value = block_size * 4 * 1024). tmp_dir: Temporary directory to use, optional (Default value = None). Returns: The decrypted file's location. """ logger = getLogger(__name__) use_openssl_only = os.getenv('SF_USE_OPENSSL_ONLY', 'False') == 'True' key_base64 = metadata.key iv_base64 = metadata.iv decoded_key = base64.standard_b64decode( encryption_material.query_stage_master_key) key_bytes = base64.standard_b64decode(key_base64) iv_bytes = base64.standard_b64decode(iv_base64) if not use_openssl_only: key_cipher = AES.new(key=decoded_key, mode=AES.MODE_ECB) file_key = PKCS5_UNPAD(key_cipher.decrypt(key_bytes)) data_cipher = AES.new(key=file_key, mode=AES.MODE_CBC, IV=iv_bytes) else: backend = default_backend() cipher = Cipher(algorithms.AES(decoded_key), modes.ECB(), backend=backend) decryptor = cipher.decryptor() file_key = PKCS5_UNPAD(decryptor.update(key_bytes) + decryptor.finalize()) cipher = Cipher(algorithms.AES(file_key), modes.CBC(iv_bytes), backend=backend) decryptor = cipher.decryptor() temp_output_fd, temp_output_file = tempfile.mkstemp( text=False, dir=tmp_dir, prefix=os.path.basename(in_filename) + "#") total_file_size = 0 prev_chunk = None logger.debug('encrypted file: %s, tmp file: %s', in_filename, temp_output_file) with open(in_filename, 'rb') as infile: with os.fdopen(temp_output_fd, 'wb') as outfile: while True: chunk = infile.read(chunk_size) if len(chunk) == 0: break total_file_size += len(chunk) if not use_openssl_only: d = data_cipher.decrypt(chunk) else: d = decryptor.update(chunk) outfile.write(d) prev_chunk = d if prev_chunk is not None: total_file_size -= PKCS5_OFFSET(prev_chunk) if use_openssl_only: outfile.write(decryptor.finalize()) outfile.truncate(total_file_size) return temp_output_file
def __init__(self, key): """Initialize a new AESCipher.""" self.block_size = 16 self.cipher = Cipher(algorithms.AES(key), modes.ECB(), default_backend())
# exchange, rather than use it directly. The server does this, and returns an encrypted # message: data = server.get_encrypted_message() iv = data["IV"] ciphertext = data["Ciphertext"] # Next we use the HKDF function to obtain a shared key, we haven't covered hashing yet, # so this bit is done for you if not shared_key: exit() from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.hkdf import HKDF hkdf = HKDF(algorithm=hashes.SHA256(), length=32, salt=None, info=b'dhexercise', backend=default_backend()) aes_key = hkdf.derive(shared_key) ### Task 4 ### # Use AES CTR mode to decrypt the server's message with the aes_key, this is the same key the server will # have derived using your shared_key from the exchange cipher = Cipher(algorithms.AES(aes_key), modes.CTR(iv), backend=default_backend()) decryptor = cipher.decryptor() message = decryptor.update(ciphertext) + decryptor.finalize() if message != None: print(message.decode("UTF-8"))
with open(plainTextfile, "rb") as inputFile: giveMeBytes = bytearray(inputFile.read()) # <-- byte array of plaintext #computes hash tag on the plaintext and appends it to byte array digest = hashes.Hash(hashes.SHA1(), backend) digest.update(giveMeBytes) some = digest.finalize()[:16] #check out iv = os.urandom(16) extendedPlainText = giveMeBytes extendedPlainText.join([extendedPlainText, some]) passDigest = hashes.Hash(hashes.SHA1(), backend) passDigest.update(passDate) key = passDigest.finalize()[:16] padder = padding.PKCS7(128).padder() paddedArray = padder.update(bytes(extendedPlainText)) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend) ciphText = cipher.encryptor().update( paddedArray) + cipher.encryptor().finalize() with open(cipherTextfile, "wb") as outputFile: out = iv + ciphText outputFile.write(out) inputFile.close() outputFile.close()
def aes128cfb8(shared_secret): cipher = Cipher(algorithms.AES(shared_secret), modes.CFB8(shared_secret), backend=default_backend()) return cipher
def encryptAES(data, key, iv): cipher = Cipher(algorithms.AES(key), modes.CTR(iv), default_backend()) encryptor = cipher.encryptor() encData = encryptor.update(data) + encryptor.finalize() return encData
def test_creates_decryptor(self, backend): cipher = Cipher(algorithms.AES(binascii.unhexlify(b"0" * 32)), modes.CBC(binascii.unhexlify(b"0" * 32)), backend) assert isinstance(cipher.decryptor(), base.CipherContext)
def aes_ecb_decrypt(key: Key, cipher_text: bytes) -> bytes: decryptor = Cipher(algorithms.AES(key=key.key_bytes), ECB(), default_backend()).decryptor() # type: CipherContext decryptor.update(cipher_text) return decryptor.finalize()
def decryptAES(ciphertext, key, iv): cipher = Cipher(algorithms.AES(key), modes.CTR(iv), default_backend()) decryptor = cipher.decryptor() return decryptor.update(ciphertext) + decryptor.finalize()
import os from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend backend = default_backend() key = b'\xfa\xd3\x99\x14\xd0<\xc7-\xc2\r\xc0\xb0\no\x9c)/\xf5K\xa2\xdc\xc2\x12C\x81k$\xf1\xc5\x0e\xde\xfa' iv = b'\xf2\xb8R\xfbG\xe3g\xdc\x0b\x10y\xb1\x85\xfc\xd6\x13' cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) #message=b"a secret messageabc " #encryptor = cipher.encryptor() ct = b'7\xc9\xf5e8!\xd1\x14\xf3kvu7\x97\x8aI\x1d\r\xdb\xbf_`\x1eDQ\x1en\x7f\xb9\x06\xc8\x84' decryptor = cipher.decryptor() decryptedmessage = decryptor.update(ct) + decryptor.finalize() print(decryptedmessage)
def aes256ctr(iv: IV, key: SecretKey, data: bytes) -> bytes: cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend = default_backend()) encryptor = cipher.encryptor() return encryptor.update(data) + encryptor.finalize()
def __init__(self, rc4key): self.rc4key = rc4key self.txcrypt = Cipher(ARC4(rc4key), mode=None, backend=default_backend()).encryptor() self.rxcrypt = Cipher(ARC4(rc4key), mode=None, backend=default_backend()).decryptor()
import os from paddingdialer import PaddingDialer from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding def to_hex(byte_ary): return ''.join(format(x, '02x') for x in byte_ary) backend = default_backend() key = os.urandom(16) iv = os.urandom(16) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) def pad_and_encrypt(msg): padder = padding.PKCS7(128).padder() padded = padder.update(msg) + padder.finalize() encryptor = cipher.encryptor() return encryptor.update(padded) + encryptor.finalize() if __name__ == '__main__': msg = b"this is block 1 this is block 2 this is block 3 this is block 4" encrypted = pad_and_encrypt(msg) class MyDialer(PaddingDialer): def check_padding(self, byte_ary): # Note that this method only leaks padding validation result.
def __init__(self, key: bytes): self.cipher = ReferenceCipher(AES(key), ECB(), default_backend())
def Mydecrypt(ciphertext, tag, iv, key): decryptor = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend=default_backend()).decryptor() return decryptor.update(ciphertext) + decryptor.finalize()