Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DKIM in .NET MailMessage and AlternativeViews

Tags:

c#

.net

dkim

I am using DKIM.NET (https://github.com/dmcgiv/DKIM.Net) to sign a MailMessage before sending it to a recipient. The problem i am facing is that the component above signs MailMessage's Body (mailMessage.Body) while I am inserting content as both HTML and plain text in the form of AlternativeViews.

The result is that my mailMessage.Body is null but the received messsage's body contains my alternative views therefore DKIM does not verify correctly.

Is there any way to resolve this problem? Maybe sign the HTML and Plain text alternative views before assigning them to the MailMessage object? Or maybe using another component?

EDIT:

Since I started this question I 've created a project at https://github.com/yannispsarras/DKIM-AlternativeViews - This is by no means complete or stable but I m posting it here in case its of any use to anyone looking to find a solution for signed alternative views in .NET.

like image 398
Yannis Avatar asked Jun 04 '11 15:06

Yannis


3 Answers

I've added full support for generating and verifying DKIM signatures in MimeKit which is open source (License: MIT) and completely free for commercial use.

If you also need SMTP, POP3, and/or IMAP support, check out MailKit which is built on top of MimeKit.

Since MimeKit and MailKit do not generate a new set of boundary strings each time they are written to a stream, they do not suffer from the problems you will face using System.Net.Mail and DKIM.Net[1] (not DKIM.Net's fault, to be clear).

To add a DKIM signature to a message in MimeKit, you would do something like this:

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);

To send the message using MailKit, you would do something like this:

using (var client = new SmtpClient ()) {
    client.Connect ("smtp.gmail.com", 465, true);
    client.Authenticate ("username", "password");
    client.Send (message);
    client.Disconnect (true);
}

Notes:

  1. Since System.Net.Mail.SmtpClient generates a new set of boundary markers for multipart messages (which is what is used when you have attachments or AlternativeViews), you cannot use DKIM.Net to sign said messages because the signature will break when you actually go to send the message because the MIME-formatted message body will have changed.
like image 71
jstedfast Avatar answered Oct 22 '22 07:10

jstedfast


You can try Mail.dll email component it supports DKIM, both: signing and validation:

http://www.limilabs.com/blog/sign-emails-with-dkim

The component is not free however, please also note that I wrote it.

like image 43
Pawel Lesnikowski Avatar answered Oct 22 '22 07:10

Pawel Lesnikowski


I've updated the read me on the DKIM.Net site to explain this limitation. It's basically due to the way System.Net.Mail.SmtpClient generates boundaries to seperate alternative views or attachments - they are new Guids so each time the message is sent the boundary id changes - if the content changes then the signing fails. The code hacks SmptClient to get the full content of the email by Sending the MailMessage using a dummy stream.

like image 1
Damien McGivern Avatar answered Oct 22 '22 07:10

Damien McGivern