I want to send a signed mail with smime with the module cryptography. But all my mail programms can't detect the subject if I sign the mail. If I don't sign the mail it shows the subject.
import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.utils import formataddr, formatdate
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import pkcs7
from jinja2 import Template
email_from = "[email protected]"
email_to = "[email protected]"
message = MIMEMultipart("mixed")
message["Subject"] = Header("mail subject", "utf-8").encode()
message["From"] = formataddr(("Sender", email_from))
message["To"] = email_to
message["Date"] = formatdate(localtime=True)
message["Auto-Submitted"] = "auto-generated"
html_template = (
Path(EMAIL_TEMPLATES_DIR) / f"{template}.html"
).read_text()
html_j2_template = Template(html_template)
html = html_j2_template.render(environment)
message.attach(MIMEText(html, "html"))
ca_cert = open(CA_CERT_PATH, "rb").read()
ca_key = open(CA_KEY_PATH, "rb").read()
cert = x509.load_pem_x509_certificate(ca_cert)
key = serialization.load_pem_private_key(ca_key, None)
options = [pkcs7.PKCS7Options.DetachedSignature]
signed_text = (
pkcs7.PKCS7SignatureBuilder()
.set_data(message.as_bytes())
.add_signer(cert, key, hashes.SHA256())
.sign(serialization.Encoding.SMIME, options)
)
with smtplib.SMTP() as server:
server.connect(25)
server.sendmail(email_from, email_to, signed_text)
And here the version with the module email for python>=3.6.
import smtplib
from email.headerregistry import Address
from email.message import EmailMessage
from email.utils import formatdate
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import pkcs7
from jinja2 import Template
email_from = "[email protected]"
email_to = "[email protected]"
message = EmailMessage()
message["Subject"] = subject_template
message["From"] = Address("Sendder", email_from)
message["To"] = Address("Receiver", email_to)
message["Date"] = formatdate(localtime=True)
message["Auto-Submitted"] = "auto-generated"
html_template = (
Path(EMAIL_TEMPLATES_DIR) / f"{template}.html"
).read_text()
html_j2_template = Template(html_template)
html = html_j2_template.render(environment)
message.set_content(html, subtype="html")
ca_cert = open(CA_CERT_PATH, "rb").read()
ca_key = open(CA_KEY_PATH, "rb").read()
cert = x509.load_pem_x509_certificate(ca_cert)
key = serialization.load_pem_private_key(ca_key, None)
options = [pkcs7.PKCS7Options.DetachedSignature]
signed_text = (
pkcs7.PKCS7SignatureBuilder()
.set_data(message.as_bytes())
.add_signer(cert, key, hashes.SHA256())
.sign(serialization.Encoding.SMIME, options)
)
with smtplib.SMTP() as server:
server.connect(25)
server.sendmail(email_from, email_to, signed_text)