【问题标题】:Generating DKIM signatures VIA Python for Custom MTA通过 Python 为自定义 MTA 生成 DKIM 签名
【发布时间】:2018-01-16 08:11:16
【问题描述】:

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

【问题讨论】:

    标签: python email base64 sha256 dkim


    【解决方案1】:

    我要感谢 Georg Zimmer 的上述回答。我在 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】:

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

      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

      【讨论】:

      • 这个答案必须被删除。不回答问题
      【解决方案3】:

      这应该会有所帮助。

      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/

      【讨论】:

      • 不知道为什么,但我不断收到与bytes 相关的错误。将所有参数转换为dkim.sign(),如下所示:dkim.sign(bytes(msg.as_string(), 'UTF-8'), b'myselector', ...) 工作。不确定这是 Python2 还是 Python3 的事情,但肯定闻起来像。
      猜你喜欢
      • 2022-01-04
      • 1970-01-01
      • 2014-07-20
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多