代码之家  ›  专栏  ›  技术社区  ›  user3482950

通过Python为自定义MTA生成DKIM签名

  •  1
  • user3482950  · 技术社区  · 9 年前

    好吧,所以我对DKIM并没有完全迷失。我知道用公钥对DNS记录进行编码和设置的一般规则,等等。我遇到的问题是将出站电子邮件的“即时”签名合并到我的邮件头中,因为我的MTA是自定义的,从头开始用python编写,而不是开箱即用。想知道是否有人有一个小小的python示例,用DKIM发送一封电子邮件,然后经历所有的动作。就像使用与dns设置中的姊妹(公共)密钥匹配的私钥生成256位加密体。

    3 回复  |  直到 9 年前
        1
  •  5
  •   James Miller    7 年前

    我要感谢乔治·齐默的上述回答。我在Python 3.6.2上运行这个时遇到了一些困难,因为一些“字节”/“字符串”项在2.x版本之后发生了变化。下面是制作MIMEMultipart(文本/HTML)并用DKIM签名的代码。我用的是dkimpy-0.6.2。

    我的第一篇StackOverflow文章。希望它能帮助你。。。

    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()
    
        2
  •  4
  •   Georg Zimmer    8 年前

    这应该会有所帮助。

    https://launchpad.net/dkimpy

    我查看了项目中包含的测试和命令行工具,以了解如何使用它。

    下面是一个代码片段,它将让您了解如何使用它。抱歉,我无法提供更多。

        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: "):]
    

    然后您可以使用smtplib发送电子邮件。

    这里可以轻松生成私钥和公钥:

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

        3
  •  2
  •   rollstuhlfahrer    7 年前

    在前面两个答案的基础上,我有一些额外的提示。

    1. 确保你跑步
    pip install dkimpy
    
    1. 生成私钥。在Unix上:
    openssl genrsa -out dkimprivatekey.pem 1024
    1. 生成公众。在Unix上:
    openssl rsa -in dkimprivatekey.pem -out public.pem -pubout
    1. 使用选择器“introduction”将公钥添加到DNS中(这是上面的示例所使用的)。
    2. 在上面的代码中提供私钥的路径和文件名(上面的示例使用 C:\dev\python\ 2048.example.com.priv )