John Hawthorn

Introducing the dkim gem

DKIM (defined in RFC 4871) is a way for email senders to claim responsibility for an email message. It works by adding an extra header to every email sent which cryptographically signs the message’s headers and body. By verifying the signature, the receiver of DKIM-signed email can be certain the emails content has been unaltered and comes from who is claimed. By taking responsibility for these messages, the sender’s reputation can allow the message to be less scrutinized by spam/phishing filters on the receivers end. For this reason, DKIM is desirable because is should increase deliverability.

I had the need to send a large amount of email through Amazon SES from a rails application. This was made very easy by the terrific fog library for accessing cloud services (I would recommend version 0.8.2 or above, which includes a bug fix I submitted). However I found no good way to DKIM sign email from ruby. There was a rubydkim gem, but it didn’t work correctly in my testing, and required an external C library.

This prompted me to create the dkim gem: a simple ruby library for DKIM signing email messages. dkim depends only on ruby built with openssl support (or jruby-openssl if you’re using jruby).

Most basic usage (which should be all that is necessary for most) is to configure the gem globally

Dkim::domain = 'example.com' Dkim::selector = 'mail' Dkim::private_key = open('private.pem').read

and then to sign any messages as needed

mail = <<eos To: someone@example.com From: john@example.com Subject: hi Howdy eos Dkim.sign(mail) # => # To: someone@example.com # From: john@example.com # Subject: hi # DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; q=dns/txt; s=mail; t=1305917829; # bh=qZxwTnSM1ywsrq0Ag9UhQSOtVIG+sW5zDkB+hPbuX08=; h=from:subject:to; # b=0mKnNOkxFGiww63Zu4t46J7eZc3Uak3I9km3IH2Le3XcnSNtWJgxiwBX26IZ5yzcT # VwJzcCnPKCScIJMQ7yfbfXmNsKVIOV6eSUqu1YvJ1fgzlSAXuDEMNFTjoto5rrdA+ # BgX849hEY/bWHDl1JJgNpiwtpl4t0Q7M4BVJUd7Lo= # # Howdy

A more detailed explanation can be found in the project’s README on github.

I hope the library proves useful to others, and would love to hear from anyone using it.