Mail protection measures: DKIM (1 1/2)

Another well extended measure to add security to the SMTP protocol (when will we stop applying patches and move on to a new protocol?) is known as DKIM.

This stands for DomainKeys Identified Mail and as you can imagine, it’s based on some PKI concepts.

The general idea is fairly simple, the server signs every mail before sending it and publishes its public key through (drums…) a DNS record! You certainly didn’t expect this one, did you?

Let’s see an example. I’ll send me an email from Facebook which is one of the big DKIM adopters. Checking the SMTP headers we find the following:

DKIM-Signature: v=1; a=rsa-sha1; d=facebookmail.com; s=q1-2009b; c=relaxed/relaxed;
q=dns/txt; i=@facebookmail.com; t=1244588132;
h=From:Subject:Date:To:MIME-Version:Content-Type;
bh=JfuLVdMFj4tE3DQJ7E3AUmszqaY=;
b=d46czRF6YMvrFofJsHpQyBOnHqKbkfO7rnjtvr5POMTEq1mLtc04NQHxeJANwQpo
aBcfAqB5vedMP9zsL6MqPQ==;

I don’t know you, but that thing at the end looks like a bunch of Base64 encoded to me. Some of the important fields here are

  • v=1, no words needed.
  • a=rsa-sha1, stands for the algorithms used.
  • d=facebookmail.com, the domain.
  • s=q1-2009b, the selector, used to determine what DNS record to query.
  • c=relaxed/relaxed, means that the system will be tolerant to modifications made to the email in transit.
  • b=(chunk of Base64 encoding), the signature itself.

Let’s query the DNS for the public key. We know that the DNS record that hold this is of the form selector._domainkey.domain, in this particular case

carlos@pattern:~$ dig @dns05.sf2p.tfbnw.net q1-2009b._domainkey.facebookmail.com
txt

; <<>> DiG 9.5.0-P2 <<>> @dns05.sf2p.tfbnw.net q1-2009b._domainkey.facebookmail.
com txt
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48012
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;q1-2009b._domainkey.facebookmail.com. IN TXT

;; ANSWER SECTION:
q1-2009b._domainkey.facebookmail.com. 3600 IN TXT “k=rsa; t=s; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrBYvYESXSgiYz

KNufh9WG8cktn2yrmdqGs9uz8VL6Mz44GuX8xJAQjpmPOb
e6p2vfTMWeztKEudwY6ei7UcZMCAwEAAQ==

;; AUTHORITY SECTION:
facebookmail.com.       172800  IN      NS      dns04.sf2p.tfbnw.net.
facebookmail.com.       172800  IN      NS      dns05.sf2p.tfbnw.net.

[follows not relevant info.]

Before doing anything I would like to get more info about this RSA key, so I’ll write a PEM container and name it pub.key

A detail worth to mention, that will save you a lot of time is that the specification states that every line should have exactly 64 chars, except the last one, which could be shorter.

—–BEGIN PUBLIC KEY—–
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrBYvYESXSgiYzKNufh9WG8cktn2yrm
dqGs9uz8VL6Mz44GuX8xJAQjpmPObe6p2vfTMWeztKEudwY6ei7UcZMCAwEAAQ==
—–END PUBLIC KEY—–

With the help of Openssl we could check the validity of this key, as follows

carlos@pattern:~$ openssl rsa -pubin -in pub.key -text
Modulus (512 bit):
00:aa:c1:62:f6:04:49:74:a0:89:8c:ca:36:e7:e1:
f5:61:bc:72:4b:67:db:2a:e6:76:a1:ac:f6:ec:fc:
54:be:8c:cf:8e:06:b9:7f:31:24:04:23:a6:63:ce:
6d:ee:a9:da:f7:d3:31:67:b3:b4:a1:2e:77:06:3a:
7a:2e:d4:71:93
Exponent: 65537 (0x10001)
writing RSA key
—–BEGIN PUBLIC KEY—–
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrBYvYESXSgiYzKNufh9WG8cktn2yrm
dqGs9uz8VL6Mz44GuX8xJAQjpmPObe6p2vfTMWeztKEudwY6ei7UcZMCAwEAAQ==
—–END PUBLIC KEY—–

So we are, in fact, dealing with a 512 bit RSA key.

What I would like to do now is decrypt the b field with the public key and compare the hashes in order to verify that I didn’t miss anything.

However there is still a little problem though. We don’t know exactly which part of the email has been included in the SHA-1 hash.

Wait a minute, who said panic? The answer resides of course in the DKIM-Signature header, specifically in the h parameter, which indicates which headers have been included in the hash process.

I tried to decrypt the signature using OpenSSL but I found it too unflexible, so I’ll do it manually. I still need to code some RSA decryption program (using OpenSSL libraries) to get the original hash and compare it to the SHA1 hash of the original message body and selected headers.

This will take me some time, so until then enjoy the reading ;)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s