def __init__( self, master_key_provider, stream_to_encrypt, max_encryption_size=DEFAULT_MAX_ENCRYPTION_SIZE_SENTINEL, encryption_context=None ): """ Provides a stream that wraps 'stream_to_encrypt' and allows reading data from the underlying stream encrypted under the provided master key. :param int max_encryption_size: (optional) Max number of bytes able to be encrypted by this StreamEncryptor. The default value differs based on the algorithm used. For GCM (the default algorithm) the default value is 2147483647 bytes. This is provided mainly for use with authenticated encryption algorithms that require verification of an authentication tag upon decryption. Because decrypting using these algorithms will buffer the entire payload into memory before returning it, this max_encryption_size provides a sanity check against encrypting payloads too large to decrypt. This is possible because encryption does not require holding the entire payload in memory. The 2147483647 byte limit was chosen because that is the maximum number of bytes that can be encrypted or decrypted by the OCI Java SDK. This is to avoid users accidentally encrypting payloads in Python that cannot be decrypted in Java. Explicitly passing this value as None will disable the size check and allow encrypting payloads up to the maximum size supported by the algorithm. :param dict encryption_context: (optional) Optional additional data to be provided as input to authenticated encryption algorithms. This must be a dict with keys that are strings and values that are strings. Keys may NOT match the prefix oci-* as that namespace is reserved for OCI internal keys that may be added to the AAD. """ self._algorithm = DEFAULT_ALGORITHM self._primary_master_key = master_key_provider.get_primary_master_key() if not self._primary_master_key: raise ValueError("master_key_provider must contain a primary master key in order to encrypt data") self._data_encryption_key = self._primary_master_key.generate_data_encryption_key( self._algorithm ) self._stream_to_encrypt = stream_to_encrypt _validate_encryption_context(encryption_context) self._encryption_context = encryption_context self._encryption_context_bytes = convert_to_bytes( convert_encryption_context_to_string(encryption_context) ) self.iv = generate_random_iv(self._algorithm.iv_len) cipher = Cipher( algorithm=self._algorithm.algorithm( self._data_encryption_key.plaintext_key_bytes ), mode=self._algorithm.mode(self.iv), backend=default_backend(), ) # use encryptor directly instead of AESGCM class # https://cryptography.io/en/latest/hazmat/primitives/aead/#cryptography.hazmat.primitives.ciphers.aead.AESGCM # so that we can optionally stream data during encryption without holding the entire payload in memory self.encryptor = cipher.encryptor() self._max_encryption_size = None if max_encryption_size is DEFAULT_MAX_ENCRYPTION_SIZE_SENTINEL: if self._algorithm.mode.name == modes.GCM.name: self._max_encryption_size = DEFAULT_MAX_GCM_ENCRYPTION_SIZE else: raise ValueError("Unrecognized algorithm provided: {}".format(str(self._algorithm))) elif max_encryption_size is not None: if not isinstance(max_encryption_size, int): raise TypeError("argument max_encryption_size must be an integer") self._max_encryption_size = max_encryption_size self._header_content = None self._buffer = b"" self._bytes_written_total = 0 self._bytes_written_excluding_header = 0 self._finalized = False self._lock = Lock() self._closed = False
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 _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]
# 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"))
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 test_instantiate_with_non_algorithm(self, backend): algorithm = object() with pytest.raises(TypeError): Cipher(algorithm, mode=None, backend=backend)
def aes128cfb8(shared_secret): cipher = Cipher(algorithms.AES(shared_secret), modes.CFB8(shared_secret), backend=default_backend()) return cipher
import os import time from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend backend = default_backend() key = os.urandom(16) iv = os.urandom(8) cipher = Cipher(algorithms.TripleDES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() start = time.time() ct = encryptor.update( b"aaa secret message jksajrulkejsljk jkjjsewiujhetsh kjhgytuoilkjhgf lkjhgfrtyuiopoi secret message jksajrulkejsljk jkjjsewiujhetsh kjhgytuoilkjhgf lkjhgfrtyuiopoia secret message jksajrulkejsljk jkjjsewiujhetsh kjhgytuoilkjhgf lkjhgfrtyuiopoi secret message jksajrulkejsljk jkjjsewiujhetsh kjhgytuoilkjhgf lkjhgfrtyuiopoi" ) + encryptor.finalize() end = time.time() #print ct print "encryption execution time: " + str(end - start) decryptor = cipher.decryptor() start = time.time() decryptor.update(ct) + decryptor.finalize() end = time.time() print "Decryption execution time: " + str(end - start)
def encrypt(data): cipher = Cipher(algorithms.AES(key), modes.CTR(nonce), backend=default_backend()).encryptor() return cipher.update(data) + cipher.finalize()
def _get_aes_cipher(key, iv, tag, mode=modes.GCM): mode = mode(iv, tag) if mode == modes.GCM else mode(iv) return Cipher(algorithms.AES(key), mode, backend=CRYPTO_BACKEND)
def update_aes(self, key): self.aes = Cipher(algorithms.AES(key), modes.CBC(self.iv), backend=default_backend())
def _aes_decrypt(self, key, iv, encrypted_data): cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=_backend) aes = cipher.decryptor() return self._strip_padding(aes.update(encrypted_data) + aes.finalize())
def decrypt_aes_128_ecb(ctxt, key): cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend) decryptor = cipher.decryptor() decrypted_data = decryptor.update(ctxt) + decryptor.finalize() message = pkcs7_strip(decrypted_data) return message
def encrypt_aes_128_ecb(msg, key): padded_msg = pkcs7_padding(msg, block_size=16) cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=backend) encryptor = cipher.encryptor() return encryptor.update(padded_msg) + encryptor.finalize()
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 decrypt_with_header(self, username): """Decrypt a credential file using the header. It handles 3DES and AES256 algorithms. Tries to parse the decrypted object into a plain credential object type. If it fails, probably due to an invalid username use to decrypt it, raises an exception. :param username: Username to use when decrypting :type username: string :return: decrypted object :rtype: SAPCredv2_Cred_Plain :raise SAPCredv2_Decryption_Error: if there's an error decrypting the object """ blob = str(self.cipher) header = SAPCredv2_Cred_Cipher(blob) # Validate supported version if header.version != 1: raise SAPCredv2_Decryption_Error("Version not supported") # Validate and select proper algorithm if header.algorithm == CIPHER_ALGORITHM_3DES: algorithm = algorithms.TripleDES elif header.algorithm == CIPHER_ALGORITHM_AES256: algorithm = algorithms.AES else: raise SAPCredv2_Decryption_Error("Algorithm not supported") def xor(string, start): """XOR a given string using a fixed key and a starting number.""" key = 0x15a4e35 x = start y = "" for c in string: x *= key x += 1 y += chr(ord(c) ^ (x & 0xff)) return y def derive_key(key, header, salt, username): """Derive a key using SAP's algorithm. The key is derived using SHA256 and xor from an initial key, a header, salt and username. """ digest = Hash(SHA256(), backend=default_backend()) digest.update(key) digest.update(header) digest.update(salt) digest.update(xor(username, ord(salt[0]))) digest.update("" * 0x20) hashed = digest.finalize() derived_key = xor(hashed, ord(salt[1])) return derived_key # Derive the key using SAP's algorithm key = derive_key(cred_key_fmt, blob[0:4], header.salt, username) # Decrypt the cipher text with the derived key and IV decryptor = Cipher(algorithm(key), modes.CBC(header.iv), backend=default_backend()).decryptor() plain = decryptor.update(header.cipher_text) + decryptor.finalize() # Perform a final xor over the decrypted content with a fixed key plain = xor(plain, 0x64FB914E) return SAPCredv2_Cred_Plain(plain)
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 __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()
def __init__(self, key): """Initialize a new AESCipher.""" self.block_size = 16 self.cipher = Cipher(algorithms.AES(key), modes.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()
def _mysql_aes_engine(key): """Create MYSQL AES cipher engine.""" return Cipher(algorithms.AES(key), modes.ECB(), default_backend())
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()
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 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 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 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
# 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 decryptAES(ciphertext, key, iv): cipher = Cipher(algorithms.AES(key), modes.CTR(iv), default_backend()) decryptor = cipher.decryptor() return decryptor.update(ciphertext) + decryptor.finalize()
def decrypt(key, iv, associated_data, ciphertext, tag): decryptor = Cipher(algorithms.AES(key), modes.GCM(iv, tag), backend=default_backend()).decryptor() decryptor.authenticate_additional_data(associated_data) return decryptor.update(ciphertext) + decryptor.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) # Pad data data = pkcs5_pad(plaintext) # 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' if isinstance(data, (six.text_type, six.string_types)): # Convert data to bytes data = data.encode('utf-8') 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