Ch3shire
Ch3shire

Reputation: 1106

Decrypting S/MIME with Python3 OpenSSL library

I have the following problem. I need to create a Python program where I can download any mail from host and decrypt it with given .pfx file and passcode. I am trying various solutions, but now I am stuck trying to force OpenSSL.crypto to simply decipher anything with given private key and certificate. The documentation and provided solutions on Google are also scarce. Any ideas?

Here is my code:

import pickle, email

file = open('cipher.pickle', 'rb')
msg_data = pickle.load(file)
file.close()

data = msg_data[0]
response = tuple(data)[1]
msg = email.message_from_bytes(response)
message = msg.get_payload()
# message = bytes(message, encoding='utf-8)

print(message) 
#gives encrypted message: 'MIAGCSqGSIb3DQEHA6CAMIACA...14g/EwQIyhd0YOdnRR0AAAAAAAAAAAAA'

from OpenSSL import crypto
ssl_pass1 = "7F63CfcUauAf"
#generated certificate from https://extrassl.actalis.it/portal/uapub/freemail?lang=en for yahoo testmail
#together with password for this certificate
with open('testmail1_yahoo.pfx', 'rb') as f:
    pfx_data = f.read() 

pfx = crypto.load_pkcs12(pfx_data, bytes(ssl_pass1, encoding='utf-8'))
pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pfx.get_privatekey())
cert = crypto.dump_certificate(crypto.FILETYPE_PEM, pfx.get_certificate())

#private key and certificate extracted from pfx so far

Upvotes: 3

Views: 3491

Answers (1)

Ch3shire
Ch3shire

Reputation: 1106

Found it.

from M2Crypto import BIO, Rand, SMIME, X509, EVP
from OpenSSL import crypto

def get_pfx(fname, password):
    f = open(fname, 'rb')
    pfx_data = f.read()
    f.close()
    pfx = crypto.load_pkcs12(pfx_data, bytes(password, encoding='utf-8'))
    return pfx

def get_cert(pfx):
    cert = pfx.get_certificate()
    fx509 = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
    x509 = X509.load_cert_string(fx509)
    return x509

def get_pkey(pfx):
    pkey = pfx.get_privatekey()
    fkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
    pkey = EVP.load_key_string(fkey)
    return pkey

def encrypt(message, x509):
    data = bytes(message, encoding='utf-8')
    buf = BIO.MemoryBuffer(data)
    sk = X509.X509_Stack()
    sk.push(x509)
    s = SMIME.SMIME()
    s.set_x509_stack(sk)
    s.set_cipher(SMIME.Cipher('aes_256_cbc'))
    p7 = s.encrypt(buf)
    return p7

def decrypt(p7, pkey, x509):
    s = SMIME.SMIME()
    s.pkey = pkey
    s.x509 = x509
    out = s.decrypt(p7)
    return_message = str(out, encoding='utf-8')
    return return_message

def decrypt_str(message, pkey, x509):
    header='Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"\n\n'
    full_message = bytes(header + message, encoding='utf-8')
    b2 = BIO.MemoryBuffer(full_message)
    p7 = SMIME.smime_load_pkcs7_bio(b2)[0]
    out_message = decrypt(p7, pkey, x509)
    return out_message

pfx = get_pfx('testmail1_yahoo.pfx', '7F63CfcUauAf')
pkey = get_pkey(pfx)
x509 = get_cert(pfx)

ciphered_message = '''
MIICLAYJKoZIhvcNAQcDoIICHTCCAhkCAQAxggG0MIIBsAIBADCBlzCBgjELMAkG
A1UEBhMCSVQxDzANBgNVBAgMBk1pbGFubzEPMA0GA1UEBwwGTWlsYW5vMSMwIQYD
VQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEsMCoGA1UEAwwjQWN0YWxp
cyBDbGllbnQgQXV0aGVudGljYXRpb24gQ0EgRzECEHJro0Uga08DJzs4igZ0Dk8w
DQYJKoZIhvcNAQEBBQAEggEARbBrrzChxi5e+ZX2tLNjdwJDj+GL5OFTX1/pHAAO
T3tWhZcX+xSmvGA6vEjMw9vaIYOaQJ6qdRMR6gC0OEUFeM/7LwfFezo4wsoKzykI
E96UUPg5bPZBAyprIljJOsTNkD4PjTT+VMKtWKh/V1x1nq58NGFn6fgNm4Rmcc2r
eNk1yEnZ1i4fMOVHnd3XwwTglilCOA7YB3BbOZ7AFNKdh6lW3jv9VrLismiU7AxF
LTF/lAcVCulynwKlxZNE3Zxvuig6KorMuQPmu3LBd1vOYzVMSC/3yYlFkVB7t0Bw
Yl0Ewf/lZB8l9qEdC0z9+ZgOb9aEQEAfsrcJDGN/ZfgRVTBcBgkqhkiG9w0BBwEw
HQYJYIZIAWUDBAEqBBDtwdanJzTnMlDtAZGw6d7TgDAyJUCfqV57Nfh1N1DRHQqj
RIbEO6ie8Cl3r53gHECJd5gTeQ0TmNI8+g9mcu01cmk=
'''

deciphered_message = decrypt_str(msg, pkey, x509)
print(deciphered_message)

Upvotes: 9

Related Questions