Skip to content Skip to sidebar Skip to footer

Generating DKIM Signatures VIA Python For Custom MTA

Ok, so I am not completely lost with DKIM. I know the general rules of encoding and setting DNS records with your public key, etc. What I am having issues with is incorporating the

Solution 1:

I would like to thank Georg Zimmer for the above answer. I ran into some difficulties running this on Python 3.6.2 as some of the "byte" / "string" items have changed since 2.x versions. Below is code to make a MIMEMultipart (text/HTML) and signed with DKIM. I used dkimpy-0.6.2.

My very first StackOverflow post. Hope it helps you...

import smtplib, dkim, time, os

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


print('Content-Type: text/plain')
print('')
msg = MIMEMultipart('alternative')
msg['From'] = 'test@example.com'
msg['To'] = 'person@anotherexample.com'
msg['Subject'] = ' Test Subject'
msg['Message-ID'] = "<" + str(time.time()) + "-1234567890@example.com" + ">"

# Create the body of the message (a plain-text and an HTML version).
text = """\
Test email displayed as text only
"""

html = """\
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
    <head>
        <title>Test DKMI Email</title>
    </head>
    <body>
        HTML Body of Test DKIM
    </body>
</html>
"""

# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')

msg.attach(part1)
msg.attach(part2)

# DKIM Private Key for example.com RSA-2048bit
privateKey = open(os.path.join('C:\\dev\\python\\', '2048.example.com.priv')).read()

# Specify headers in "byte" form
headers=[b'from', b'to', b'subject', b'message-id']

# Generate message signature
sig = dkim.sign(msg.as_bytes(), b'introduction', b'example.com', privateKey.encode(), include_headers=headers)
sig = sig.decode()

# Add the DKIM-Signature
msg['DKIM-Signature'] = sig[len("DKIM-Signature: "):]

# Send the message via local SMTP server.
s = smtplib.SMTP('localhost')
# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.quit()

Solution 2:

To build on the previous two answers, I have a few additional tips.

  1. Be sure you run
pip install dkimpy
  1. Generate the private key. On Unix:
openssl genrsa -out dkimprivatekey.pem 1024
  1. Generate the public. On Unix:
openssl rsa -in dkimprivatekey.pem -out public.pem -pubout
  1. Add the public key to your DNS with the selector "introduction" (which is what the example above uses.
  2. Provide the path and filename to your private key in the code above (the example above uses C:\dev\python\ and 2048.example.com.priv)

Solution 3:

This should help.

https://launchpad.net/dkimpy

I looked at the tests and the command line tools included in the project to learn how to use it.

Here is a code fragment which will give you an idea of how to use it. Sorry I can't provide more.

    self.dkim_private = open(os.path.join(settings.PROJECT_DIR, 'private_key.pem')).read()
    ... snip ...
    msg = MIMEMultipart('alternative')
    msg['From'] = "{0} <{1}>".format(self.sendfrom_name, self.sendfrom)
    msg['To'] = self.sendto
    msg['Date'] = formatdate(localtime=True)
    msg['Message-ID'] = self.message_id
    msg['Subject'] = self.subject

    msg.attach(MIMEText(unicodedata.normalize('NFKD', self.body_text), 'plain'))
    msg.attach(MIMEText(self.body, 'html'))

    sig = dkim.sign(msg.as_string(), 'myselector',
                    from_domain, self.dkim_private,
                    include_headers=['from', 'to', 'subject', 'message-id'])
    msg['DKIM-Signature'] = sig[len("DKIM-Signature: "):]

Then you use can use smtplib to send the email.

The private and public keys can be generated easily here:

https://www.port25.com/support/domainkeysdkim-wizard/


Post a Comment for "Generating DKIM Signatures VIA Python For Custom MTA"