Tock me some time, but I got my problem solved.
We changed the encryption to pgp and here is how I generate my keys / encrypt / decrypt files / blobs (i.e. a mailattachment)
import pgpy
from pgpy.constants import PubKeyAlgorithm, KeyFlags, HashAlgorithm, SymmetricKeyAlgorithm, CompressionAlgorithm
class PgpDecryptor:
"""
A class that can encrypt / decrypt files with pgp encryption.
"""
# in die config packen?
filename_key = "key.pem"
def __init__(self):
self.key = None
self.message = None
self.encrypted_message = None
self.filename_org = None
self.filename_encrypted_PGPMessage = None
self.passphrase = None
def generate_pgp_key(self, filename_key, passphrase=None):
"""
Generates a new pgp key pair with a passphrase. T
:param filename_key: The path for the key storage
:param passphrase: The passphrase to lock / unlock the private key
"""
self.key = pgpy.PGPKey.new(PubKeyAlgorithm.RSAEncryptOrSign, 4096)
uid = pgpy.PGPUID.new('Martin Kraemer', email='martin.kraemer@sixt.com')
# All diese Verschluesselungstechniken / usages usw. sind moeglich (keine Preferenz)
# Man kann ebenfalls nen expiration date mitgeben (in etwa so: key_expiration=timedelta(days=365))
self.key.add_uid(uid, usage={KeyFlags.Sign, KeyFlags.EncryptCommunications, KeyFlags.EncryptStorage},
hashes=[HashAlgorithm.SHA256, HashAlgorithm.SHA384, HashAlgorithm.SHA512,
HashAlgorithm.SHA224],
ciphers=[SymmetricKeyAlgorithm.AES256, SymmetricKeyAlgorithm.AES192,
SymmetricKeyAlgorithm.AES128],
compression=[CompressionAlgorithm.ZLIB, CompressionAlgorithm.BZ2, CompressionAlgorithm.ZIP,
CompressionAlgorithm.Uncompressed])
# protect a key with a phrase like "Schnarr"
# this phrase is needed to use the private key
if passphrase:
self.key.protect(passphrase, SymmetricKeyAlgorithm.AES256, HashAlgorithm.SHA256)
save_to_file(filename_key, str(self.key), mode="w")
save_to_file(f"pub_{filename_key}", str(self.key.pubkey), mode="w")
def encrypt_file(self, file_to_encrypt=None, filename_encrypted_file=None, key_path=None):
"""
Encrypts a file with a pgp key.
:param file_to_encrypt: The path to the file we want to encrypt
:param filename_encrypted_file: The path to the file we've encrypted
:poram key_path: Sets the path to an specific key, otherwise the key in the same folder (key.pem) is used
"""
if file_to_encrypt:
self.filename_org = file_to_encrypt
if filename_encrypted_file:
self.filename_encrypted_PGPMessage = filename_encrypted_file
self.__get_message()
self.key = self.__get_pgp_key(key_path)
self.encrypted_message = self.key.pubkey.encrypt(self.message)
save_to_file(self.filename_encrypted_PGPMessage, str(self.encrypted_message), mode="w")
def decrypt_blob(self, blob_to_decrypt, filename_decrypted_file, key_path=None, passphrase=None):
"""
Decrypts an blob that is pgp encrypted, using the private we've already created and saves the result
to the given file
:param blob_to_decrypt: If set, encrypt the message directly and not from file
:param filename_decrypted_file: The filename of the decrypted file
:poram key_path: Sets the path to an specific key, otherwise the key in the same folder (key.pem) is used
:poram passphrase: The passphrase used to unlock the private key
"""
self.key = self.__get_pgp_key(key_path)
self.message = pgpy.PGPMessage.from_blob(blob_to_decrypt)
# unlock the key with the passphrase
with self.key.unlock(passphrase) as k:
save_to_file(filename_decrypted_file, self.key.decrypt(self.message).message, mode='wb')
def decrypt_file(self, file_to_decrypt, filename_decrypted_file, key_path=None, passphrase=None):
"""
Decrypts an blob that is pgp encrypted, using the private we've already created and saves the result
to the given file
:param file_to_decrypt: The file we want to decrypt (path to the file)
:param filename_decrypted_file: The filename of the decrypted file
:poram key_path: Sets the path to an specific key, otherwise the key in the same folder (key.pem) is used
:poram passphrase: The passphrase used to unlock the private key
"""
self.key = self.__get_pgp_key(key_path)
self.message = pgpy.PGPMessage.from_file(file_to_decrypt)
# unlock the key with the passphrase
with self.key.unlock(passphrase) as k:
save_to_file(filename_decrypted_file, self.key.decrypt(self.message).message, mode='wb')
def __get_pgp_key(self, key_path=None):
if key_path:
key, _ = pgpy.PGPKey.from_file(key_path)
else:
key, _ = pgpy.PGPKey.from_file(self.filename_key)
return key
def __get_message(self):
with open(self.filename_org, "rb") as f:
self.message = pgpy.PGPMessage.new(f.read())
def save_to_file(file_name, content, path=".", mode='wb'):
with open(f"{path}/{file_name}", mode=mode) as f:
if mode.startswith('w'):
f.write(content)
else:
f.append(content)
and here is how to use it:
# encrypt example:
pgp_decryptor = PgpDecryptor()
pgp_decryptor.generate_pgp_key(filename_key="test.pem")
# pgp_decryptor.generate_pgp_key(filename_key="test.pem", passphrase="schnarr")
pgp_decryptor.encrypt_file(file_to_encrypt="43630766.PDF", filename_encrypted_file="43630766_encrypted.pdf", key_path="test.pem")
pgp_decryptor.decrypt_file("43630766_encrypted.pdf", "43630766_decrypted.pdf", key_path="test.pem")
# pgp_decryptor.decrypt_file("43630766_encrypted.pdf", "43630766_decrypted.pdf", key_path="test.pem", passphrase="schnarr")