I'm currently trying to encrypt and decrypt passwords using the python cryptography library and RSA. The key generation works fine, the encryption works but when it comes to decrypting the password, I'm faced with this traceback error message:
raise ValueError("Ciphertext length must be equal to key size.")
My encryption and decryption code looks like this:
class AppCryptography():
def generate_rsa_keypair(self, bits=4096):
return rsa.generate_private_key(
public_exponent=65537,
key_size=bits,
backend=default_backend()
)
def load_private_key(self, pem_file_path):
with open(pem_file_path, "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None,
backend=default_backend()
)
return private_key
def load_public_key(self, pem_file_path):
with open(pem_file_path, "rb") as key_file:
public_key = serialization.load_pem_public_key(
key_file.read(),
backend=default_backend()
)
return public_key
def encrypt_password(self, public_key, password):
password = bytes(password) if not isinstance(password, bytes) else password
public_key = public_key if isinstance(public_key, RSAPublicKey) else self.load_pem_public_key(
public_key_pem_export=public_key
)
cipher_pass = public_key.encrypt(
password,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None
)
)
return str(base64.b64encode(cipher_pass))
def decrypt(self, private_key, cipher_pass):
cipher_pass = base64.b64decode(cipher_pass) if not isinstance(cipher_pass, bytes) else cipher_pass
private_key = private_key if isinstance(private_key, RSAPrivateKey) else self.load_pem_private_key(
private_key_pem_export=private_key
)
plain_text_pass = private_key.decrypt(
cipher_pass,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None
)
)
return str(plain_text_pass)
And the error happens when I run this script:
crypter = AppCryptography()
backend_public_key = crypter.load_public_key(dir_path + "/util/keys/backend_public_key.pem")
frontend_private_key = crypter.load_private_key(dir_path + "/util/keys/frontend_private_key.pem")
encrypted_password = crypter.encrypt_password(backend_public_key, password)
signature = crypter.sign_data(frontend_private_key, password)
backend_private_key = crypter.load_private_key(dir_path + "/util/keys/backend_private_key.pem")
cleartext = crypter.decrypt(backend_private_key, encrypted_password)
My stacktrace show that the error comes from the decrypt function but I'm unable to see where the error is in the function definition.
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 411, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 650, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/models.py", line 114, in password
cleartext = crypter.decrypt(backend_private_key, encrypted_password)
File "/Users/Me/Desktop/Projects/Flask-Dream/project_app/util/crypto.py", line 121, in decrypt
label=None
File "/Users/Me/anaconda/envs/flask_dream/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 397, in decrypt
raise ValueError("Ciphertext length must be equal to key size.")