在.NET MailMessage和AlternativeViews中使用DKIM

8
我正在使用DKIM.NET (https://github.com/dmcgiv/DKIM.Net) 对MailMessage进行签名,然后将其发送给收件人。我面临的问题是,上述组件会对MailMessage的正文(mailMessage.Body)进行签名,而我以HTML和纯文本形式插入内容到AlternativeViews中。
结果是我的mailMessage.Body为null,但接收到的消息正文包含我的替代视图,因此DKIM无法正确验证。
有没有办法解决这个问题?也许在将它们分配给MailMessage对象之前签署HTML和纯文本替代视图?或者使用另一个组件?
编辑:
自从我开始提出这个问题以来,我已经在https://github.com/yannispsarras/DKIM-AlternativeViews创建了一个项目-这绝不是完整或稳定的,但我在这里发布它,以防它对于寻找.NET中签名替代视图的解决方案的任何人有用。

3个回答

3
我已经为 MimeKit 添加了完整的 DKIM 签名生成和验证支持,它是开源的(许可证:MIT),并且完全免费用于商业用途。
如果您还需要 SMTP、POP3 和/或 IMAP 支持,请查看基于 MimeKit 构建的 MailKit
由于 MimeKit 和 MailKit 在每次写入流时不会生成新的边界字符串,因此它们不会遇到使用 System.Net.Mail 和 DKIM.Net[1](明确地说,这不是 DKIM.Net 的问题)时可能遇到的问题。
要向消息添加 DKIM 签名,您可以像这样操作:
var message = CreateMyMessage ();
var headersToSign = new [] { HeaderId.From, HeaderId.To, 
    HeaderId.Subject, HeaderId.Date };
var signer = new DkimSigner ("C:\my-dkim-key.pem") {
   AgentOrUserIdentifier = "@eng.example.net",
   Domain = "example.net",
   Selector = "brisbane",
};

message.Sign (signer, headersToSign, 
    DkimCanonicalizationAlgorithm.Relaxed, 
    DkimCanonicalizationAlgorithm.Simple);

使用MailKit发送消息,您可以像这样操作:
using (var client = new SmtpClient ()) {
    client.Connect ("smtp.gmail.com", 465, true);
    client.Authenticate ("username", "password");
    client.Send (message);
    client.Disconnect (true);
}

注意事项:

  1. 由于System.Net.Mail.SmtpClient为多部分消息生成一组新的边界标记(当您有附件或备用视图时使用),因此您不能使用DKIM.Net对此类消息进行签名,因为当您实际发送消息时,签名将会失效,因为MIME格式的消息正文已经发生了变化。

2

嗨Pawel,谢谢你的回答 - 你的组件速度有多快?我还能使用本地的SmtpClient吗? - Yannis
如果您必须使用本机的SmtpClient,您可以使用Mail.dll创建电子邮件,将其保存到磁盘,然后使用SmtpDeliveryMethod.SpecifiedPickupDirectory。我从未比较过Mail.dll和SmtpClient的速度,但它应该是可比较的。 - Pawel Lesnikowski
我需要一些在你的博客中找不到的更多信息。mail.dll使用什么技术?它是一个COM组件吗?它是托管代码吗?如何创建一个邮件发送组件而不对基线进行测试? - Yannis
Mail.dll完全由托管代码编写。与Mono、.NET 2.0、3.0、3.5和4.0兼容。它不仅是电子邮件发送组件,还包括IMAP、POP3、SMTP客户端、电子邮件解析器、模板引擎等功能。.NET SmtpClient并不能代表它,因为它只能完成Mail.dll所能实现的一小部分功能。 - Pawel Lesnikowski

1
我已经更新了DKIM.Net网站上的read me,以解释这个限制。基本上是由于System.Net.Mail.SmtpClient生成用于分隔替代视图或附件的边界的方式 - 它们是新的Guid,因此每次发送消息时边界ID都会更改 - 如果内容更改,则签名失败。该代码通过使用虚拟流发送MailMessage来黑客SmptClient以获取电子邮件的完整内容。

非常感谢您的反馈。自从我发布了这个问题后,我决定编写自己的SmtpClient库,以便通过.NET应用程序发送DKIM签名电子邮件。不幸的是,我已经尝试过声称可以解决此问题的SMTP库,但最终发现它们有不同的问题集(最常见的是性能限制)。 - Yannis
@Yannis,你真的应该看看MailKit,我向你保证它没有任何性能限制,并且由于它使用PIPELINING,应该比System.Net.Mail.SmtpClient更快。 - jstedfast
我很感激,但这是一个非常古老的问题。自那时以来发生了很多事情,但还是谢谢你发表建议。 - Yannis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接