## Friday, June 18, 2010

### Facebook's DKIM RSA key should be crackable

If Facebook sends you a mail they will sign it using DKIM. Here are the headers from a mail I received the other day:
 DKIM-Signature: v=1; a=rsa-sha1; d=facebookmail.com; s=q1-2009b;  c=relaxed/relaxed; q=dns/txt; [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */; t=1276438946; h=From:Subject:Date:To:MIME-Version:Content-Type; bh=Yn52UpOukFZwR3a9mIx7vzTOepw=; b=RGMm2Lp2Jms1yLuanKsEhSfSLpXQ15Y9RaGb0KgzWfGqcnEFUeQlhazkJXuT0+Nh 3iNqMAfwE6TvLQmiv55YUA==;

The signature itself is the b field (RGMm2Lp2Jms1yLuanKsEhSfSLpXQ15Y9RaGb0KgzWfGqcnEFUeQlhazkJXuT0+Nh
3iNqMAfwE6TvLQmiv55YUA==
). The a field tells you the algorithm used (in this case, it's RSA/SHA1). The d field tells you the domain of the entity that signed the mail, and the s field tells you which key you need to retrieve (q1-2009b).

So, let's go get that key (the q field tells you that this can be retrieved by a DNS TXT query):
$dig -ttxt q1-2009b._domainkey.facebookmail.com; <<>> DiG 9.4.3-P3 <<>> -ttxt q1-2009b._domainkey.facebookmail.com;; global options: printcmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19407;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 3;; QUESTION SECTION:;q1-2009b._domainkey.facebookmail.com. IN TXT;; ANSWER SECTION:q1-2009b._domainkey.facebookmail.com. 434 IN TXT "k=rsa\; t=s\; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrBYvYESXSgiYzKNufh9WG8cktn2yrmdqGs9uz8VL6Mz44GuX8xJAQjpmPObe6p2vfTMWeztKEudwY6ei7UcZMCAwEAAQ==" The answer section gives the actual key. It's an RSA public key, so let's turn that into a file that OpenSSL can handle: -----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKrBYvYESXSgiYzKNufh9WG8cktn2yrmdqGs9uz8VL6Mz44GuX8xJAQjpmPObe6p2vfTMWeztKEudwY6ei7UcZMCAwEAAQ==-----END PUBLIC KEY----- Feed that file to OpenSSL and we can find out information about it. $ openssl rsa -noout -text -pubin < facebook.key 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:93Exponent: 65537 (0x10001)

So, Facebook is using an 512-bit RSA key. Wikipedia says: "Keys of 512 bits have been shown to be practically breakable in 1999 when RSA-155 was factored by using several hundred computers and are now factored in a few weeks using common hardware."

Aside: that modulus is a 154 digit number. Good old pexpr can dump it in decimal for you: