VS.NET 2010/2012 Users Click Here   

HOMECONTACT PRODUCTS DOWNLOADS PURCHASE TESTIMONIALS FORUMS COMPANY CONTACT
Home
Products
Downloads
Purchase
Licensing
Licensing FAQ
Software Updates
Support Forums
Testimonials
Feature Requests
Guarantee
About Us
Contact Us
Hosting Companies
Privacy Policy
   
Shopping Cart


Search

DomainKeys and DKIM with aspNetEmail and SmarterMail

by Dave 5. October 2010 08:13

Note:This code example will only be valid until aspNetEmail v4.0 releases. Once it releases, the aspNetDkim will no longer be needed, as the DKIM and DomainKeys signing functionality will be baked into aspNetEmail.

I recently had a customer (thanks Noah!) email me and ask how to perform a DomainKeys and/or DKIM  signed mail merge against the SmarterMail queue directory.

Great Question!

It turns out its relatively easy. What you will need to do, is:

a)Tie into aspNetEmail's new Queuing namespace, that has a new SmarterMail class.
b)Tie into the new RenderEmailContents event
c)In that event, sign the message, and return the signed contents to be written to the queue folder.

Here is the code example that demonstrates this functionality.

 

private void SmarterMailTest()
{
	
	//create the EmailMessage object, and set some basic properties
	EmailMessage msg = new EmailMessage();
	msg.From = "me@mycompany.com";
	msg.AddTo( "##EmailAddress##" );
	msg.Subject = "Order Confirmation";

	//a very simple body for testing purposes
	msg.Body = "Hi ##FirstName## ##LastName##, here is your order total ##Amount##";
	
	//add the render event, so we can sign the message
	msg.RenderEmailContents += new RenderEmailContentsEventHandler( SignForSmartermail );

	//set the SmarterMail queuing			
	aspNetEmail.Queuing.SmarterMail sm = new aspNetEmail.Queuing.SmarterMail( msg );
	sm.SpoolDirectory = "c:\\temp\\";

	//GetDataTable() is a method that fetches our data, and returns a DataTable object
	DataTable dt = GetDataTable();
	sm.SendMailMerge( dt );

}
private void SignForSmartermail( object sender, RenderEmailContentsEventArgs e )
{
	string contents = e.Contents;

	//sign the contents with DomainKeys
	contents = SignDKForSmartermail( contents );
	
	//we can also sign with Dkim
	//contents = SignDkimForSmartermail( contents );

	//reset the contents
	e.Contents = contents;


}


private string SignDKForSmartermail( string contents )
{
	DomainKeys dkeys = new DomainKeys( contents );


	//parse the private rsa key that was generated by openSSL.exe
	
	//we can get it from the file
	dkeys.DKCertificate = DKCertificate.ParsePemFile( "testing\\rsa.private" );

	dkeys.Canonicalization = CanonicalizationType.Simple;

	//the dns record selector
	dkeys.Selector = "testing";
	
	//sign the email contents
	string signedContents = dkeys.SignMail();

	return signedContents;

}


private string SignDkimForSmartermail( string contents )
{
	Dkim dk = new Dkim( contents );
	
	dk.Identity = "@mycompany.com";

	//parse the private rsa key that was generated by openSSL.exe
	//we can get it from the file
	dk.DKCertificate = DKCertificate.ParsePemFile( "testing\\rsa.private" );

	dk.SendingDomain = "mycompany.com";

	//the dkim dns record selector (based upon our DNS server settings
	dk.Selector = "testing";

	dk.HeaderNamesOption = HeaderNamesOptions.AllMessageHeaders;

	//sign the email contents
	string signedContents = dk.SignMail();

	return signedContents;
}

As always, if anyone has any questions, comments, or feature requests, feel free to let me know.

Thanks!
Dave Wanta

DomainKeys and DKIM Beta Plugin Available

by Dave 4. October 2010 05:18

For those people that need to implement either DomainKeys or DKIM, I have a plug-in that is pubically available for aspNetEmail. This plug in has been in use by a number of customers over the past few years.  I’m now making it available to the public, and general users of aspNetEmail.

This functionality will be baked into aspNetEmail v4.0, and will then become part of aspNetEmail.

Currently, it’s a separate plug-in for those 3.x users.

If you would like to request a beta version of aspNetDkim, simply request it using the online comments form here.

Here’s some more information about using DomainKeys and DKIM taken directly from the Readme file

==========================
aspNetDkim
==========================
aspNetDkim supports both DomainKeys and DKIM standards for signing email. Although both of these standards are similar, and use the same basic techniques, they do produce different results.

DomainKeys (RFC link: http://rfc.net/rfc4870.html )
==========================
DomainKeys is the pre-cursor for DKIM (Domain Keys Identified Mail). Although DomainKeys does not have the flexibility of DKIM, it is still useful.

The DomainKeys standard basically takes a hash of the email, and embeds that hash as a special header at the top of the email. The hash is created using a Public and Private key pair. The recipient then verifies the hash, by using the public key of the sender.  The public key of the sender is stored in sender’s DNS server as a specially formatted TXT (text) record.


DKIM
==========================
DKIM has its history in DomainKeys, but it is basically an upgraded version, with more functionality.  Like DomainKeys, it also takes a hash of the email, and stores the hash in the header of the email.  This is based upon a Public and Private key pair.  The main differences between DomainKeys and DKIM, is that DKIM has more options for how the email content is hashed, and stored in the email header.


DNS
===========================
Both DomainKeys and DKIM depend upon a public key to be stored in a TXT DNS record. The same key can be used by both DomainKeys and DKIM.

These keys are generated (per the RFC) using the open source program called OpenSSL. OpenSSL can be downloaded from: http://www.openssl.org/


OpenSSL
==========================
Running the OpenSSL.exe will create a openssl prompt in a DOS window.

The following commands are used to generate a public and private key pair.

openssl> genrsa -out rsa.private 768

openssl> rsa -in rsa.private -out rsa.public -pubout -outform PEM

The first command generates a 768 bit key in a text file called rsa.private.

The second command takes that file (rsa.private) as input, and generates the public key in a text file called rsa.public. Both of these keys are in the PEM (Privacy Enhancement for Internet Electronic Mail)format. aspNetDkim can read these files natively, so there isn’t any need to convert to .pfx or .p12 type certificates.

See the RFC for more information on deploying the public key to the sender’s DNS server.

aspNetDkim -- DomainKeys code sample
==========================
aspNetDkim has a class called DomainKeys that is used for signing out going email using DomainKeys.

aspNetDkim has a class called Dkim that is used for signing out going email using DKIM.

*NOTE* It’s very important that the email contents are not altered, modified, or rearranged in any format, after they leave aspNetEmail. This includes added special headers to the content, or adding outgoing signatures to the body. Any changes to the email content will result in a different hash, than what was calculated by aspNetDkim, thereby breaking the DomainKeys signature. DKIM does allow limited modifications after the email is hashed. However, allowing these modifications to take place may compromise the integrity of your email.

The following is a code examples use aspNetEmail to send an email.

====================================================
  DOMAIN KEYS CODE EXAMPLE
====================================================

private static void DomainKeysTest()
{
	EmailMessage msg = new EmailMessage();
	msg.FromAddress = "dave@example.com";
	msg.FromName = "dave james";
	msg.To = "some_recipient@somecompany.com";
	msg.Subject = "this is a simple domainkeys testing message";
	msg.Body = "this is a test";

	//get the email contents from aspNetEmail
	string emailContents = msg.ToString();

	//sign the email
	string 	signedContents = SignDkim( emailContents, CanonicalizationType.Simple );

	//reset the SmtpData on the EmailMessage object
	//if the SmtpData property is set, aspNetEmail will send that data, and override any other settings
	msg.SmtpData = signedContents;

	//save to a file, just for testing purposes. We can open this file in notepad
	//or in something like Outlook Express.
	msg.SaveToFile( "c:\\temp\\" );

	//we can direct send
	//DirectSend.Send( msg );

	//use a relay server
	//however, the relay server cannot modify the content in any way, or it will break the DomainKeys signature
	//msg.Sever = "mail.mycompany.com";
	//msg.Send();

	//or write to a spool directory, such as MSPIckup
	//msg.SendToMSPickup();

}

Here is the method used for signing the email:

private static string SignDomainKeys( string emailContents, CanonicalizationType ct )
{
	DomainKeys dkim = new DomainKeys( emailContents );

	//parse the private rsa key that was generated by openSSL.exe
	//we can get it from the file
	dkim.DKCertificate = DKCertificate.ParsePemFile( "testing\\rsa.key.private" );

	dkim.SendingDomain = "test.com";

	dkim.Canonicalization = ct;
	
	//the dkim dns record selector (based upon our DNS server settings)
	dkim.Selector = "testing";

	//sign the email contents
	string signedContents = dkim.SignMail();
	
	//also, we can write the email directly to a file (as some queues will accept emails in their native RFC2822 format)
	dkim.SignMailToFile( "c:\\MyMailServer\\SomeQueue\\" );


	//this is the resulting DKIM header value. We won't do anything with it, just show it for
	//demo purposes
	string header = dkim.DomainKeysHeader();
	Console.WriteLine( header );


	return signedContents;

}

 

====================================================
  DKIM CODE EXAMPLE
====================================================

private static void DkimTest()
{

	EmailMessage msg = new EmailMessage("127.0.0.1");
	msg.FromAddress = "dave@example.com";
	msg.FromName = "dave james";
	msg.To = "some_recipient@somecompany.com";
	msg.Subject = "this is a simple Dkim  testing message";
	msg.Body = "this is a test";

	//get the email contents from aspNetEmail
	string emailContents = msg.ToString();

	//sign the email
	string signedContents = SignDkimRelaxed( emailContents );

	//reset the SmtpData on the EmailMessage object
	//if the SmtpData property is set, aspNetEmail will send that data, and override any other settings
	msg.SmtpData = signedContents;

	//save to a file, just for testing purposes. We can open this file in notepad
	//or in something like Outlook Express.
	msg.SaveToFile( "c:\\temp\\" );

	//we can direct send
	//DirectSend.Send( msg );

	//use a relay server
	//however, the relay server cannot modify the content in any way, or it will break the DKIM signature
	//msg.Sever = "mail.mycompany.com";
	//msg.Send();

	//or write to a spool directory, such as MSPIckup
	//msg.SendToMSPickup();

}

public static string SignDkimRelaxed( string contents )
{
	Dkim dk = new Dkim( contents );
	
	//parse the private rsa key that was generated by openSSL.exe
	//we can get it from the file
	dk.DKCertificate = DKCertificate.ParsePemFile( "testing\\rsa.key.private" );

	//relaxed headers
	dk.HeaderCanonicalization = CanonicalizationType.Relaxed;
	dk.BodyCanonicalization = CanonicalizationType.Relaxed;
	
	//the dkim dns record selector (based upon our DNS server settings)
	dk.Selector = "testing";


	//sign the email contents
	string signedContents = dk.SignMail();
	
	//we can optionally save to a file, if we want to inspect it
	dk.SignMailToFile( "c:\\temp\\" );
	
	//return the singed contents
	return signedContents;
}

Again, if you would like to request a beta version of aspNetDkim, simply request it using the online comments form here.

As always, I apprecate any feedback. If you have any, feel free to share.

Thanks!
Dave Wanta 

 

 

Testimonial

BTW, I really like your software. We purchased the aspNetEmail last year to solve an iCalendar issue we had. Your software really works well and the interfaces are very easy to understand. I only had to look at the help files once or twice; that is a very good sign. I really love to see quality software and don’t mind paying for it! "

D. Eveland

Read more testimonials
ListNanny aspNetDNS aspNetEmail aspNetPOP3 aspNetMX IPMuncher aspNetMIME aspNetPING aspNetTraceRoute aspNetIMAP aspNetMHT