Decrypt data using cryptography package giving error "ValueError: Encryption/decryption failed."

Viewed 605
import base64
import os.path
from shutil import copyfile
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.backends.openssl.rsa import _RSAPublicKey, _RSAPrivateKey
from asym_crypto_yaml import (decrypt_value, encrypt_value, Encrypted,
load_private_key_from_file, load_public_key_from_file,
generate_new_private_key, generate_new_public_key,
load, dump, NUMBER_OF_BYTES_PER_ENCRYPTED_CHUNK, KEY_CHUNK_SIZE,
SUPPORTED_KEY_SIZES, generate_private_key_to_file, generate_private_key_to_file, generate_public_key_to_file,
encrypt_value_and_print ,add_secret_to_yaml_file, decrypt_yaml_file_and_write_encrypted_file_to_disk,
reencrypt_secrets_and_write_to_yaml_file)
from functools import reduce

def test_add_secret_to_yaml_file():
    private_key_output_filename = "/home/asy/private_key.private"
    public_key_output_filename = "/home/asy/public_key.public"
    private_key = generate_private_key_to_file(private_key_output_filename)
    public_key = generate_public_key_to_file(private_key_output_filename, public_key_output_filename)

    yaml_file_fixture = "/home/asy/saml.yml"
    yaml_file_to_append_to = "/home/asy/saml_du.yml"
    test_key_to_encrypt = ['FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET', 'AWS_S3_BUCKET', 'SECRET_TOKEN', 'TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET',
    'TWITTER_OAUTH_TOKEN', 'TWITTER_OAUTH_TOKEN_SECRET', 'LINKEDIN_API_KEY', 'LINKEDIN_SECRET_KEY']
    print ("################################ENCRYPT YAML########################################")
    before_dict = None
    with open(yaml_file_to_append_to, "r") as f:
        before_dict = load(f)
    #  Encrypt data in yml file
    for test_key in test_key_to_encrypt:
        print ('Encrypted key is:', test_key)
        print ('Encrypted value is:', before_dict[test_key])
        add_secret_to_yaml_file(test_key, before_dict[test_key], public_key_output_filename, yaml_file_to_append_to)

    print ("################################DECRYPT YAML########################################")
    before_dict = None
    with open(yaml_file_to_append_to, "r") as f:
        before_dict = load(f)
    # Decrypt data from yml file (Using same function)
    for test_key_value in test_key_to_encrypt:
        print ('key is', before_dict[test_key_value])
        test_encrypted_key_value = decrypt_value(before_dict[test_key_value], private_key)
        print ("decrypt data", test_encrypted_key_value)
    # 

def decrypt_data():
    private_key_output_filename = "/home/asy/private_key.private"
    public_key_output_filename = "/home/asy/public_key.public"
    private_key = generate_private_key_to_file(private_key_output_filename)
    public_key = generate_public_key_to_file(private_key_output_filename, public_key_output_filename)

    yaml_file_to_append_to = "/home/asy/saml_du.yml"
    test_key_to_encrypt = ['FACEBOOK_APP_ID', 'FACEBOOK_APP_SECRET', 'AWS_S3_BUCKET', 'SECRET_TOKEN', 'TWITTER_CONSUMER_KEY', 'TWITTER_CONSUMER_SECRET',
    'TWITTER_OAUTH_TOKEN', 'TWITTER_OAUTH_TOKEN_SECRET', 'LINKEDIN_API_KEY', 'LINKEDIN_SECRET_KEY']
    print ("################################DECRYPT YAML########################################")
    before_dict = None
    with open(yaml_file_to_append_to, "r") as f:
        before_dict = load(f)

    for test_key_value in test_key_to_encrypt:
        print ('key is', test_key_value)
        print ('value is', before_dict[test_key_value])
        test_encrypted_key_value = decrypt_value(before_dict[test_key_value], private_key)
        print ("decrypt data", test_encrypted_key_value)

if __name__ == "__main__":
    test_add_secret_to_yaml_file()
    # decrypt_data()

sample yml file:

SECRET_TOKEN:            "d4e5783de1c74c7a4e3a27578df6gdgf6g786g8df7g6g87d6fgb709"
FACEBOOK_APP_ID:         "35864341"
FACEBOOK_APP_SECRET:     "759a1e7sd7fvyfsd473"
TWITTER_CONSUMER_KEY:    "1UrRKJDF8SD7FSDF3S"
TWITTER_CONSUMER_SECRET: "5W7TE8KJJk787bnG0s"
TWITTER_OAUTH_TOKEN:     "716397744-3rHXFkFkjKjkjK78PQ5"
TWITTER_OAUTH_TOKEN_SECRET: "DuDJKFSD89SDFD"
LINKEDIN_API_KEY:        "2vjkJKjk4"
LINKEDIN_SECRET_KEY:     "5KLSJDFsE"
GMAIL_USERNAME:          "username@gmail.com"
GMAIL_PASSWORD:          "PASSWORD"
AWS_ACCESS_KEY_ID:       "ASDKLSDJFIA"
AWS_SECRET_ACCESS_KEY:   "7ASDFJksdfjskdlf87sdfKb"
AWS_S3_BUCKET:           "bucket"

development:
  MAILER_HOST: "localhost:3000"

test:
  MAILER_HOST: "localhost:3000"

production:
  MAILER_HOST: "domain.com"

I am using "asym_crypto_yaml" yaml package to write encrypted value in .yml file. I am not able to decrypt value from different decrypt function (decrypt_data()). Above code only decrypt value if I execute code first time. But from second time its giving "encryption/decryption error".

My objective is to decrypt data from yml file. Little help will be appreciated.

2 Answers

The error is triggered because the private key used in decrypt_data() for decryption does not belong to the public key used in test_add_secret_to_yaml_file() to perform the encryption. Therefore, decryption with this private key fails.

The problem can be solved by using in decrypt_data() the private key of the key pair generated in test_add_secret_to_yaml_file(). To do this, remove the generate_private_key_to_file() and generate_public_key_to_file() calls (to generate and store a key pair) in decrypt_data(). The required private key can be loaded with load_private_key_from_file() from the file where it was stored in test_add_secret_to_yaml_file().

This ValueError: Encryption/decryption failed. Error is also thrown by the hazmat class when the data you want to encrypt is too large for the size of key that you generated.
Try again by using larger key size like this.

private_key = rsa.generate_private_key(public_exponent=65537, key_size = 4096)

but keep in mind it will increase time to generate key, that is one of the biggest disadvantage of RSA encryption algorithm.

Related