Signing your SES mail with DKIM using PHPMailer and Route 53

If you use Amazon’s Simple Email Service to send email you might have noticed your messages have an unfortunate via listing in gmail – email-bounces.amazonses.com. To fix this, you need to sign your mail with DKIM before you send it.

To deliver mail, I was using PHPMailer with a custom SES delivery method. To start signing messages, I followed these steps:

Generate a key

I started by using the form here. The nice thing about the form is that it generates the keys and gives you a zip file that contains the keys, instructions on what to set your DNS txt entry to plus some sample PHP code for use with PHPMailer.

Unfortunately the key is 1024 bits which didn’t work when I tried to add a txt entry in Route 53 using the AWS management console, I kept getting a TXTRDATATooLong error. There seems to be a 255 character limit for TXT entries. Switching to a 768 bit key solved the problem. Here’s the code to generate the key:

openssl genrsa -des3 -passout pass:<change-me> -out .htkeyprivate 768
openssl rsa -in .htkeyprivate -passin pass:<change-me> -pubout -out .htkeypublic

(change the <change-me> password)

Add an entry to Route53

Add the following TXT entry to your domain in Route 53:

Name: mailer._domainkey
Type: TXT - Text
Value: "v=DKIM1; k=rsa; g=*; s=email; h=sha1; t=s; p=<key from .htkeypublic>;"

Sign and send a test email to yourself

You’re now ready to send yourself a test email to see if it has worked. Make sure you cc check-auth@verifier.port25.com in your message – port25.com runs a handy verifier that will reply to you with details about what worked (or didn’t work) in your message.

// blah blah blah, normal PHPMailer setup
$mail->DKIM_domain = 'yourdomain.com';
$mail->DKIM_private = 'path/to/dkim.key.private';
$mail->DKIM_selector = 'mailer';
$mail->DKIM_passphrase = '<change-me>';
// and then you send the email...

Hopefully everything worked and your via text in gmail no longer includes email-bounces!