C#发送DKIM签名的邮件

DKIM(DomainKeys Identified Mail) 是一个电子邮件验证标准——域名密钥识别邮件标准,邮件系统可据此标准判断邮件是否为垃圾邮件。

它的工作原理是生成私钥(private key)/公钥(public key)对,将公钥以TXT记录的形式存放在 DNS 服务器中,发送邮件时选择相应的邮件字段(比如From, To, Subject)通过私钥生成签名信息并附加到邮件头之后进行发送。目标邮件服务器收到邮件后,根据发件人的域名从 DNS 查询中得到公钥,然后用该公钥验证邮件头中的签名信息是否合法。

我们通过 C# 代码成功发送了 DKIM 签名的邮件,具体操作步骤如下:

1、通过 dkimcore.org 提供的工具生成私钥以及需要添加至 DNS 中的包含公钥的记录

a)打开 http://dkimcore.org/tools/,在 Domain Name 中输入发送邮箱的域名,点击 Generate;

b)假设域名是 cnblogs.biz,我们会得到如下图所示的三个数据——Selector(1362200600.cnblogs), Private key, DNS记录(名称为1362200600.cnblogs._domainkey,值是以v=DKIM1;开头以冒号结尾的部分[不包含冒号,图中未显示])。

2、在DNS服务器中添加TXT记录

3、检查DNS记录是否添加成功

打开 http://dkimcore.org/tools/ ,在 Check a published DKIM Core Key 栏目中输入 Selector 与 Domain,点击 check;如果添加成功,会显示“This is a valid DKIM key record”。见下图:

4、写 C# 代码发送 DKIM 签名的邮件

a) 从 github 签出 DKIM.Net (https://github.com/dmcgiv/DKIM.Net)的源代码并编译得到 DKIM.Net.dll;

b) 在项目中添加 DKIM.Net.dll 的引用,然后编写 C# 发送邮件的代码,示例代码如下:

static void SendDkimMail()
{
    var privateKey = @"-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDg7KQwmXRzrw+zsn5USz4GGee8vspz6CyA+y5J0yIS9Up2WJP3
ySaxmIrUBpcLs7/u4rfDfUygAFBsGaU1A9pBxDF5Kfp/V/aWdSN6PClkqcS8jjxE
qj4AbL1Ax74nZniWCLr3ttXezrUUjuNk2YR7gmedKmxKUqRuqKmrnYpCTQIDAQAB
AoGBAMID/iEZzXSYVjAIUKY/fRHgOJ/750CRzgm4IRZ3M9Yslf19rK05atIYpe/8
e0AR3gaetCrBo14Ex1pnyLTxTMp98IZmk+lVPNU2bGhc/QQ7YpgMUga3b+MP7C3w
/N7k8L2dUv0hjjLWKknWimNFfE8mWsYrAlC4I5YtP6Q2qjPhAkEA9WAN5ESsPHXl
FWrPEISor2D3qX55XiOlZnkf1drnwVS72vK8yCP28yBtCuthK9OT4q5QSHwFWh47
UEp3nsozKQJBAOqp5JFB8zfgoaLhbQ5R3voZxrNmDMpsI0eWpua+cjTd67sgjBk7
7Fbb8kN1nzXCq/QbqB+gwmq8YMMdHLxD/oUCQHG55lZhOc7/+YBWs8f9JE28zKzj
MI9gSB3Zj9bHkdi6VCMjlDnS6XdAFSoVdEEi3A0ZK56c1MIy9ty81vpizxkCQED9
CCYKY7dn6JvZXoCGv//3v4XTj1tIE4Ux/csNl0d45l4Op34dkFiF1VRFcPBMl56l
QixwMyeoQAwJNfoVwpkCQCxr2Jp+NlQIXFPRP8Hotq9JkkqDQYCvpWLsQVLvV8NJ
vcubkzQjVRqo3N6nob826y3eysX5Ag8ThnvfBbPaA6o=
-----END RSA PRIVATE KEY-----";
    var domain = "cnblogs.biz";
    var selector = "1362200600.cnblogs";
    var headers = new string[] { "From", "To", "Subject" };

    var mailMsg = new MailMessage();            
    mailMsg.To.Add(new MailAddress("收件人邮箱"));
    mailMsg.From = new MailAddress("test@cnblogs.biz", "test");
    mailMsg.Subject = "test";
    mailMsg.Body = "test";           

    //对邮件进行DKIM签名
    var domainKeySigner = new DomainKeySigner(PrivateKeySigner.Create(privateKey), 
        domain, selector, headers);
    mailMsg.DomainKeySign(domainKeySigner);

    var smtpClient = new SmtpClient("mail.cnblogs.biz");
    smtpClient.Send(mailMsg);
}

c) 运行代码发出邮件

5、接收邮件并检查邮件是否通过 DKIM 验证。

我们测试时邮件发向的是 gmail 邮箱,在 gmail 中该邮件的阅读窗口选择“显示原始邮件”,如果通过了 DKIM 验证,会看到如下的信息:

DomainKey-Signature: a=rsa-sha1; c=simple; d=cnblogs.biz; h=From:To:Subject;
 q=dns; s=1362200600.cnblogs;
 b=JCzfhjomQPJK6m5GCLt/I/K4oQ7...;

注:如果您想用友好的 Selector 名称(文中是1362200600.cnblogs),可以随意设定,只要代码中与 DNS 记录中保持一致即可。比如用 dkim 名称,在 DNS 添加记录时名称就是 dkim._domainkey ,代码则为 var selector = "dkim";

posted @ 2013-03-02 14:07 dudu 阅读(...) 评论(...) 编辑 收藏