31

看起来有一些很棒的库可以在 C#/.NET 上对电子邮件进行 DomainKeys 签名,但我很难找到对 PHP 的相同类型的支持。也许我没有找对地方?

我找到的唯一一个是http://php-dkim.sourceforge.net/;它看起来非常h​​acky,只支持PHP4。考虑到 PHP 的流行程度,以及域名密钥对于将电子邮件分类为非垃圾邮件的重要性,我希望有更好的工具;你知道吗?你还有什么技巧可以推荐的吗?

额外信息:我正在使用外部 SMTP 提供商,因为我每天需要发送数千封电子邮件。

4

4 回答 4

25

我建议在 MTA 级别提供 DKIM 支持,以便默认情况下对给定域的所有服务器生成的电子邮件进行签名。(除非您有充分的理由不签署所有服务器生成的域电子邮件)。

在我用 dkim-milter 和 sendmail(在我的例子中是 CentOS 5.2)上谷歌搜索在 LAMP 上设置 DKIM 的最佳起点是Jeff Atwood 关于通过代码发送电子邮件的帖子

我同意他的观点,你应该解决的前两件事是反向 PTR 记录和 DKIM 签名。

也很重要:

  1. 用于发送电子邮件的盒子的 IP 地址尚未被列入黑名单。
  2. 确保 postmaster@emailsendingdomain.com 是一个有效的邮箱
  3. 如果您的服务器生成的电子邮件需要看起来来自其他地方(例如需要来自表单中提供的姓名/电子邮件的联系表格),请遵循这些电子邮件标题指南

这是我使用的电子邮件 IP 地址黑名单检查器

这 5 件事可能会解决您 95% 的电子邮件送达率问题。

Fedora/dkim-milter/postfix 的这个指南也很好。

我用于我的应用程序的 PHP 邮件库是 PHPMailer 5.1,它具有 DKIM 支持(并且仅是 PHP 5),但经过研究,我决定在 sendmail 级别实现是一个更好的解决方案。如您所见,即使是 PHPMailer 5.1 的作者也不建议在 PHP 邮件库级别使用 DKIM 是最好的解决方案http://dkim.worxware.com/

祝你好运。

于 2010-05-22T02:32:58.643 回答
16

这是我关注了一段时间的问题,在网络上的任何地方都无法在此线程中找到原始问题的明确答案。我现在已经能够使用 PHP/Pear 实现发送 DKIM 签名的 SMTP 电子邮件。以下是所需的步骤。

  1. 我从http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/找到了 DKIM 的修改版本(您可以通过http://www.ra726.net/php-dkim.zip下载它)。如果您已经实现了 DKIM 并且只需要使其与 SMP 邮件一起使用,那么您所需要的就是 dkim.php 文件,正如博客所说,该文件经过轻微修改以处理作为数组传递的标头。在我的代码中,我将其命名为 dkimNEW.php。

  2. 确保包含大多数标头,以便 MTA 在您签名后不会修改邮件。在我有限的研究中,添加最多的标头是 Date 和 Message-ID 标头,因此我的标头数组如下所示: 注意:我使用它来发送 html 电子邮件,更改以适应!此外,将您的域添加为 Message-ID 的最后一部分

    $headers = array(
        'Subject' => $subject,
        'From' => $from,
        'To' => $to,
        'MIME-Version' => '1.0',
        'Date' => date('r'),
        'Message-ID' => '<'.sha1(microtime(true)).'@yourdomain.com>',
        'Content-Type' => 'text/html',
        'Content-Transfer-Encoding' => 'quoted-printable',
    ); // end $headers
    
  3. 然后,您将使用上面提到的修改后的 dkim.php 对您的电子邮件进行签名并将签名添加到 headers 数组,也就是

    require 'dkimNEW.php';
    $dkim = AddDKIM($headers, $subject, $body);
    $headers['DKIM-Signature'] = $dkim;
    

其余代码是使用 PHP/Pear 通过 SMTP 发送电子邮件的普通代码。完整的工作代码是:

<?php
    require_once 'Mail.php';
    require_once 'Mail/mime.php';
  // set all of the parameters
    $subject = 'Test of DKIM';
    $from = 'My Name <myname@mydomain.com>';
    $to = 'First Recipient <recipient1@domain.com>';
    $pbody ='<html><head></head><body><h1>Done! DKIM test</h1>Result, next?</body></html>';
    $text = strip_tags($pbody);

    // create the headers
    $headers = array(
        'Subject' => $subject,
        'From' => $from,
        'To' => $to,
        'MIME-Version' => '1.0',
        'Date' => date('r'),
        'Message-ID' => '<'.sha1(microtime(true)).'@mydomain.com>',
        'Content-Type' => 'text/html',
        'Content-Transfer-Encoding' => 'quoted-printable',
    ); // end $headers


    // create the message
    $mime = new Mail_mime("\n");
    $mime->setTXTBody($text);
    $mime->setHTMLBody($pbody);

    // always call these methods in this order
    $body = $mime->get();
    $headers = $mime->headers($headers);

    require 'dkimNEW.php' ;
    $dkim = AddDKIM($headers, $subject, $body);
    $headers['DKIM-Signature'] = $dkim;

    // create the smtp mail object
    $smtp_params = array(
        'host' => 'mail.mydomain.com',
        'auth' => true,
        'username' => 'myUserName',
        'password' => 'myPassWord',
    ); // end $smtp_params
    $smtp = Mail::factory('smtp', $smtp_params);

    // send the message

    $recipients = array('recipient1@domain.com', 'recipient2@domain.com');
    $mail = $smtp->send($recipients, $headers, $body);

?>

PS。以防万一你没有注意到,用你自己的替换值!

因此,使 DKIM 与 SMTP 电子邮件(或实际上是 PHP 邮件)一起工作所需要做的就是确保您指定由 MTA 添加到电子邮件中的所有标头,然后签署标头、主题和正文消息,最后在您的标题中包含该签名部分。

于 2012-10-23T00:45:24.507 回答
11

你试过吗:phpMailDomainSigner它支持面向对象风格的 DKIM-Signature 和 DomainKey-Signature。

这里有一些例子:

// Create mailDomainSigner Object
include_once './lib/class.mailDomainSigner.php';

$mds = &new mailDomainSigner($domain_priv,$domain_d,$domain_s);
$new_data = $mds->sign(
                $mail_data,
                "Message-ID:Subject:From:Content-Type:MIME-Version:Content-Transfer-Encoding:Received:To:Date",
                true,true,false);
于 2011-01-29T07:06:18.813 回答
10

一个仅用于 DKIM 的类,它是 PHPMailer 的衍生产品,但在尊重 RFC 和简洁明了的代码方面有所改进:

https://sourceforge.net/projects/dkim-class-php/

例子 :

include_once('dkim.class.php');
$dkim = new DKIM();
$dkim_header = $dkim -> get_DKIM_header($to, $subject, $message, $headers);
mail($to, $subject, $message, $dkim_header.$headers);
于 2012-04-29T19:14:15.337 回答