def wrap_key_owner(passphrase, data_key): """ data_key must be encoded Using argon2.low_level function, which is technically a hazmat function, but it doesn't appear to have any dangerous problems. We can't use the argon2.PasswordHasher() functions because they compress the hash and metadata using Blake2b and you can't extract the raw bytes of the hash or salt, which we need for the SIV. """ #derive key using passphrase and salt salt = os.urandom(16) derived_key = argon2.low_level.hash_secret_raw( passphrase.encode(), salt, time_cost=1, memory_cost=8, parallelism=1, hash_len=32, type=argon2.low_level.Type.I) # wrap the data key using the derived key siv = SIV(derived_key) ciphertext = siv.seal(data_key) # add salt to the start of ciphertext ciphertext = salt + ciphertext return ciphertext
def encrypt(self: object) -> [bytes, str]: passphrase = self._gen_xkcd_phrase() salt = os.urandom(self.SALT_SIZE) key = self._derive_key(passphrase.encode('utf-8'), salt) siv = SIV(key) nonce = os.urandom(self.NONCE_SIZE) ciphertext = salt + nonce + siv.seal(self._archive(), [nonce]) return ciphertext, passphrase
def enc_file(filepath): key = SIV.generate_key() siv = SIV(key) nonce = os.urandom(16) with open(filepath, 'r') as myfile: data = myfile.read().encode() ciphertext = siv.seal(data, [nonce]) return (key, nonce, nonce + ciphertext) #returning ciphertext with the nonce (first 16 bytes) return None
def encryption_machine(msg): encrypt = [] key = SIV.generate_key() siv = SIV(key) nonce = os.urandom(16) # create a random nonce ciphertext = siv.seal(msg, [nonce]) # msg is in byte encrypt.append(ciphertext) encrypt.append(nonce) encrypt.append(key) return encrypt # we create a list with the nonce, the key and the ciphertext to be able to decrypt it later
class AES(Encryption): default_options = {"salt": None} pubkey = None def setup(self): password = self.ask_password() # Generate Salt if not self.config["salt"]: salt = urandom(SALT_SIZE) self.config["salt"] = binascii.hexlify(salt) # Derive key from password and initialize SIV key = self.derive_key(password) self.engine = SIV(key) def derive_key(self, password): salt = binascii.unhexlify(self.config["salt"]) pw_bytes = bytes(password, "utf-8") dk = hash_secret_raw( pw_bytes, salt, time_cost=ARGON2_TIME_COST, memory_cost=ARGON2_MEMORY_COST, parallelism=ARGON2_PARALLELISM, hash_len=ARGON2_HASH_LEN, type=ARGON2_TYPE, ) return dk def encrypt(self, data): nonce = urandom(NONCE_SIZE) if not isinstance(data, bytes): data = bytes(data, "utf-8") sealed_data = self.engine.seal(data, [nonce]) return (sealed_data, nonce) def decrypt(self, payload): data = self.engine.open(payload[0], [payload[1]]) return data
def test_seal(self): """Ensure the 'seal' method passes all AES-SIV test vectors""" for ex in PMACSIVExample.load(): siv = SIV(ex.key, PMAC) ciphertext = siv.seal(ex.plaintext, ex.ad) self.assertEqual(ciphertext, ex.ciphertext)