如何通过 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")
我有一个 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")