I've tried various approaches to signing an email message using Python. There's the M2Crypto library mentioned here but that library no longer builds / works properly with Python 3.4+. There's a newer library cryptography which works well for encrypting - see example here. I have some code that does the signing, but it's ugly:
def signEmailFrom(msg, fromAddr):
""" Signs the provided email message object with the from address cert (.crt) & private key (.pem) from current dir.
Returns signed mail string, in format
Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m"
Content-Disposition: attachment; filename="smime.p7m"
Content-Transfer-Encoding: base64
See RFC5751 section 3.4
The reason for choosing this format, rather than multipart/signed, is that it prevents the delivery service
from applying open/link tracking or other manipulations on the body.
"""
eml = msg.as_bytes()
with NamedTemporaryFile('wb') as tmpFile:
tmpFile.file.write(eml)
tmpFile.file.close()
pubCertFile = fromAddr + '.crt'
privkeyFile = fromAddr + '.pem'
if os.path.isfile(pubCertFile) and os.path.isfile(privkeyFile):
myout = subprocess.run(['openssl', 'smime', '-in', tmpFile.name, '-sign', '-signer', pubCertFile, '-inkey', privkeyFile, '-md','sha256', '-nodetach'], capture_output=True)
if myout.returncode == 0:
sout = myout.stdout.decode('utf8')
return sout
else:
return None
else:
print('Unable to open public and private key files for fromAddr', fromAddr)
return None
My question:
- Is there way to use
pyca/cryptography, or other 3.x compatible library, to produce the signed mail?