def decrypt(self, payload): payload_mac, iv, ciphertext = payload[:32], payload[32:57], payload[ 57:] generated_mac = self.gen_mac(iv, ciphertext) if sha256(payload_mac).digest() != sha256(generated_mac).digest(): raise Exception( "EncryptedFileStorage - Error opening file. Wrong MAC") return decrypt_sym(ciphertext, self.masterkey, iv)
def test_encrypt_decrypt_sym(self): # generate 256-bit key key = os.urandom(32) iv, cyphertext = crypto.encrypt_sym('data', key) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') plaintext = crypto.decrypt_sym(cyphertext, key, iv) self.assertEqual('data', plaintext)
def test_decrypt_with_wrong_key_fails(self): key = os.urandom(32) iv, cyphertext = crypto.encrypt_sym('data', key) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') wrongkey = os.urandom(32) # 256-bits key # ensure keys are different in case we are extremely lucky while wrongkey == key: wrongkey = os.urandom(32) plaintext = crypto.decrypt_sym(cyphertext, wrongkey, iv) self.assertNotEqual('data', plaintext)
def test_decrypt_with_wrong_iv_fails(self): key = os.urandom(32) iv, cyphertext = crypto.encrypt_sym('data', key) self.assertTrue(cyphertext is not None) self.assertTrue(cyphertext != '') self.assertTrue(cyphertext != 'data') # get a different iv by changing the first byte rawiv = binascii.a2b_base64(iv) wrongiv = rawiv while wrongiv == rawiv: wrongiv = os.urandom(1) + rawiv[1:] plaintext = crypto.decrypt_sym( cyphertext, key, iv=binascii.b2a_base64(wrongiv)) self.assertNotEqual('data', plaintext)
def _decrypt_storage_secret_version_1(self, encrypted_secret_dict): """ Decrypt the storage secret. Storage secret is encrypted before being stored. This method decrypts and returns the decrypted storage secret. Version 1 of storage secret format has the following structure: '<storage_secret id>': { 'cipher': 'aes256', 'length': <secret length>, 'secret': '<encrypted storage_secret>', }, :param encrypted_secret_dict: The encrypted storage secret. :type encrypted_secret_dict: dict :return: The decrypted storage secret. :rtype: str :raise SecretsException: Raised in case the decryption of the storage secret fails for some reason. """ # calculate the encryption key if encrypted_secret_dict[self.KDF_KEY] != self.KDF_SCRYPT: raise SecretsException("Unknown KDF in stored secret.") key = scrypt.hash( self._passphrase_as_string(), # the salt is stored base64 encoded binascii.a2b_base64(encrypted_secret_dict[self.KDF_SALT_KEY]), buflen=32, # we need a key with 256 bits (32 bytes). ) if encrypted_secret_dict[self.KDF_LENGTH_KEY] != len(key): raise SecretsException("Wrong length of decryption key.") if encrypted_secret_dict[self.CIPHER_KEY] != self.CIPHER_AES256: raise SecretsException("Unknown cipher in stored secret.") # recover the initial value and ciphertext iv, ciphertext = encrypted_secret_dict[self.SECRET_KEY].split( self.IV_SEPARATOR, 1) ciphertext = binascii.a2b_base64(ciphertext) decrypted_secret = decrypt_sym(ciphertext, key, iv) if encrypted_secret_dict[self.LENGTH_KEY] != len(decrypted_secret): raise SecretsException("Wrong length of decrypted secret.") return decrypted_secret
def _decrypt_storage_secret(self, encrypted_secret_dict): """ Decrypt the storage secret. Storage secret is encrypted before being stored. This method decrypts and returns the decrypted storage secret. :param encrypted_secret_dict: The encrypted storage secret. :type encrypted_secret_dict: dict :return: The decrypted storage secret. :rtype: str :raise SecretsException: Raised in case the decryption of the storage secret fails for some reason. """ # calculate the encryption key if encrypted_secret_dict[self.KDF_KEY] != self.KDF_SCRYPT: raise SecretsException("Unknown KDF in stored secret.") key = scrypt.hash( self._passphrase_as_string(), # the salt is stored base64 encoded binascii.a2b_base64( encrypted_secret_dict[self.KDF_SALT_KEY]), buflen=32, # we need a key with 256 bits (32 bytes). ) if encrypted_secret_dict[self.KDF_LENGTH_KEY] != len(key): raise SecretsException("Wrong length of decryption key.") if encrypted_secret_dict[self.CIPHER_KEY] != self.CIPHER_AES256: raise SecretsException("Unknown cipher in stored secret.") # recover the initial value and ciphertext iv, ciphertext = encrypted_secret_dict[self.SECRET_KEY].split( self.IV_SEPARATOR, 1) ciphertext = binascii.a2b_base64(ciphertext) decrypted_secret = decrypt_sym(ciphertext, key, iv) if encrypted_secret_dict[self.LENGTH_KEY] != len(decrypted_secret): raise SecretsException("Wrong length of decrypted secret.") return decrypted_secret