如何通过 Python Openssl 解密 .p7m 文件

How To Decrypt a .p7m File via Python Openssl

我有一个 python 程序,它遍历电子邮件并下载附件文件。 现在我想处理上述电子邮件的内容。

我有一个像这样的密钥“c34pj34365g0394hg”和一个 smime_post.key 文件,内容如下:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJrTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIeHcIC+7nTU4CAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBC/DGRNkgo3TizIHH3TWnHqBIIJ
UPu99JJuhB6hcHYS5UxgACXAdO6xOmXV7C1JUduGmTfNin0YwkJN7SMG6nOhGuxN
6BWczg5ENf1b3btIB6LwxyCFY+O/lvgzXMWrOr6/0XEQt3p7WTqOxbZ94nEcki1u
vZT9QdtveNAoZrZ48RyY1uoo2l3GLbSumSKaHx88lGLecMtnbUhFbwfE6Z6l6msK
VIi6kq+g1qiFD62xenyyS20UHkTgPy8CsJdllDDfU+aPxkOzTmfAdEHeIUzYwNPu

最重要的当然是带有加密内容的 smime.p7m 文件。 我找不到对这个主题有用的东西。

我在另一个电子邮件导入(来自意大利)中遇到了类似的问题,我可以使用以下代码加密文件:

def remove_signature(fileString):
    p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, fileString)
    bio_out = crypto._new_mem_buf()
    res = _lib.PKCS7_verify(p7._pkcs7, _ffi.NULL, _ffi.NULL, _ffi.NULL, bio_out,
                            _lib.PKCS7_NOVERIFY | _lib.PKCS7_NOSIGS)

    if res == 1:
        return (crypto._bio_to_string(bio_out).decode('UTF-8'))
    else:
        errno = _lib.ERR_get_error()
        errstrlib = _ffi.string(_lib.ERR_lib_error_string(errno))
        errstrfunc = _ffi.string(_lib.ERR_func_error_string(errno))
        errstrreason = _ffi.string(_lib.ERR_reason_error_string(errno))
        print(f"------------------------------------\berrstrreason: {errstrreason}---------------------------\b")
        print(f"------------------------------------\berrno: {errno}---------------------------\b")
        print(f"------------------------------------\berrstrlib: {errstrlib}---------------------------\b")
        print(f"------------------------------------\berrstrfunc: {errstrfunc}---------------------------\b")
        return ""

我的猜测是,我必须解密 .key 文件并将其用作证书? 如果有人对此有一些经验,我将不胜感激。

给我一些时间,但我的问题已经解决了。 我们将加密更改为 pgp,这是我生成密钥/加密/解密文件/blob(即邮件附件)的方式

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)

下面是使用方法:

# 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")