{"id":1008,"date":"2012-12-02T18:05:02","date_gmt":"2012-12-02T16:05:02","guid":{"rendered":"http:\/\/www.limilabs.com\/blog\/?p=1008"},"modified":"2014-05-28T10:40:45","modified_gmt":"2014-05-28T08:40:45","slug":"sign-emails-with-dkim","status":"publish","type":"post","link":"https:\/\/www.limilabs.com\/blog\/sign-emails-with-dkim","title":{"rendered":"Sign emails with DKIM"},"content":{"rendered":"<p>DKIM is short for DomainKeys Identified Mail. It is a method for associating a domain name to an email message. It allows a person, role, or organization (domain owner) to <strong>claim some responsibility for the message<\/strong>. <\/p>\n<p>DKIM adds a digital signature to the email message headers (using DKIM-Signature field), which can be validated by recipients. Signer also puts his\/hers public key in the TXT DNS record. <strong>The verifier recovers the signer&#8217;s public key from the specified DNS<\/strong> record, and then <strong>verifies that the signature matches the message&#8217;s content<\/strong>.<\/p>\n<p>Usually DKIM signature covers several most important message headers (From:, Subject:) and the message body.<\/p>\n<p>The DKIM-Signature header field apart from the actual signature signature contains the domain name, the list of covered header fields, the signing algorithm, and the method by which text snippets are simplified for signing purposes (canonicalization). <\/p>\n<h2>Create private\/public key for DKIM<\/h2>\n<p>The easiest way to generate public and private key for DKIM purposes is to use OpenSSL. The output is already Base64 encoded and ready to be used when createing DNS record and signing an email.<\/p>\n<p>To create <strong>a private key<\/strong>:<br \/>\n<code>openssl genrsa -out private.key 1024<\/code><\/p>\n<p>To create <strong>a public key<\/strong> using the private key:<br \/>\n<code>openssl rsa -in private.key -pubout -out public.key<\/code><\/p>\n<p>Full listing follows:<\/p>\n<p><code><br \/>\nc:\\>openssl genrsa -out dkim_private.key 1024<\/p>\n<p>Loading 'screen' into random state - done<br \/>\nGenerating RSA private key, 1024 bit long modulus<br \/>\n...++++++<br \/>\n..++++++<br \/>\ne is 65537 (0x10001)<\/p>\n<p>c:\\>openssl rsa -in dkim_private.key -pubout -out dkim_public.key<br \/>\nwriting RSA key<\/p>\n<p>c:\\><br \/>\n<\/code><\/p>\n<h2>Create DNS record for DKIM<\/h2>\n<p>Copy your public key from dkim_public.key file.  Copy everything between &#8220;&#8212;&#8211;BEGIN PUBLIC KEY&#8212;&#8211;&#8221; and &#8220;&#8212;&#8211;END PUBLIC KEY&#8212;&#8211;&#8221; and remove new lines:<\/p>\n<p><code><br \/>\n-----BEGIN PUBLIC KEY-----<br \/>\nMIG...AQAB<br \/>\n-----END PUBLIC KEY-----<br \/>\n<\/code><\/p>\n<p>Simplest DKIM DNS record has following format:<\/p>\n<p><code>\"v=DKIM1; p=MIG...AQAB; t=s\"<\/code><\/p>\n<ul>\n<li>v &#8211; is DKIM version (must be DKIM1)<\/li>\n<li>p &#8211; is your public key<\/li>\n<li>t=s &#8211; specifies that domain does not send mail using any subdomains<\/li>\n<ul>\n<p>You can create such record manually or use many online DKIM DNS Record Creation Tools.<\/p>\n<p>Now choose your selector name. It can be any string, it can identify departments or even individual users. In this example we&#8217;ll use &#8220;alpha&#8221; as our selector name.<\/p>\n<p>The name of the DKIM TXT record is created as follows:<\/p>\n<p><code>selector + \"._domainkey\"<\/code><\/p>\n<p>e.g.: alpha._domainkey<\/p>\n<p>Now you&#8217;ll need to add this record to your DNS.<\/p>\n<h2>Send DKIM signed message<\/h2>\n<p>Sending DKIM signed messages is simple using Mail.dll <a href=\"\/mail\">.NET email component<\/a>. First we&#8217;ll use <em>PemReader<\/em> class to create <em>RSACryptoServiceProvider <\/em> from the private key stored on disk in pem format. Then we&#8217;ll use <em>Smtp <\/em>class to connect and authenticate to our SMTP server and send the email message:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ C#\r\n\r\nRSACryptoServiceProvider rsa = new PemReader().ReadPrivateKeyFromFile(@&quot;d:\\dkim_private.key&quot;);\r\n\r\nIMail email = Limilabs.Mail.Fluent.Mail.Text(&quot;text&quot;)\r\n       .From(&quot;alice@example.com&quot;)\r\n       .To(&quot;bob@mail.com&quot;)\r\n       .Subject(&quot;subject&quot;)\r\n       .DKIMSign(rsa, &quot;alpha&quot;, &quot;example.com&quot;)\r\n       .Create();\r\n\r\nusing(Smtp smtp = new Smtp())\r\n{\r\n    smtp.Connect(&quot;smtp.example.com&quot;);  \/\/ or ConnectSSL for SSL\r\n    smtp.UseBestLogin(&quot;alice@example.com&quot;, &quot;password&quot;);\r\n    smtp.SendMessage(email);                     \r\n    smtp.Close();   \r\n} \r\n<\/pre>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\n' VB.NET\r\n\r\nDim rsa As RSACryptoServiceProvider = New PemReader().ReadPrivateKeyFromFile(&quot;d:\\dkim_private.key&quot;)\r\n\r\nDim email As IMail = Mail _\r\n\t\t.Text(&quot;text&quot;) _\r\n\t\t.From(&quot;alice@example.com&quot;) _\r\n\t\t.&#x5B;To](&quot;bob@mail.com&quot;) _\r\n\t\t.Subject(&quot;subject&quot;) _\r\n\t\t.DKIMSign(rsa, &quot;alpha&quot;, &quot;example.com&quot;) _\r\n\t\t.Create()\r\n\r\nUsing smtp As New Smtp()\r\n\tsmtp.Connect(&quot;smtp.example.com&quot;)\r\n\t' or ConnectSSL for SSL\r\n\tsmtp.UseBestLogin(&quot;alice@example.com&quot;, &quot;password&quot;)\r\n\tsmtp.SendMessage(email)\r\n\tsmtp.Close()\r\nEnd Using\r\n<\/pre>\n<h2>Verify DKIM signed message<\/h2>\n<p>Mail.dll <a href=\"\/mail\">.NET email component<\/a> automatically queries DNS and validates DKIM signed messages:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\n\/\/ C#\r\n\r\nvar eml = ...;\r\nIMail email = new MailBuilder().CreateFromEml(eml);\r\nif (email.IsDKIMSigned)\r\n{\r\n    bool isValid = email.CheckDKIMSignature();\r\n}\r\n<\/pre>\n<pre class=\"brush: vb; title: ; notranslate\" title=\"\">\r\n' VB.NET\r\n\r\nDim eml = ...\r\nDim email As IMail = New MailBuilder().CreateFromEml(eml)\r\nIf email.IsDKIMSigned Then\r\n    Dim isValid As Boolean = email.CheckDKIMSignature()\r\nEnd If\r\n<\/pre>\n<p>You can use <a href=\"\/mail\">.NET IMAP component<\/a> to <a href=\"\/blog\/receive-unseen-emails-using-imap\">receive messages from the IMAP server<\/a>.<\/p>\n<h2>Verify DKIM signed message &#8211; details<\/h2>\n<p>Under the hood the recipient of the email queries the DNS server for TXT record for selector._domainkey.domainName (in our example it is: &#8220;alpha._domainkey.example.com&#8221;). Selector and domain name are stored inside the DKIM-Signature: email header. From the DNS record public key is extracted:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nC:\\&gt;nslookup\r\nDefault Server:  UnKnown\r\nAddress:  192.168.0.1\r\n\r\n&gt; set type=TXT\r\n&gt; alpha._domainkey.example.com\r\nServer:  UnKnown\r\nAddress:  192.168.0.1\r\n\r\nNon-authoritative answer:\r\nalpha._domainkey.example.com      text =\r\n\r\n        &quot;v=DKIM1; p=MIG...AQAB; t=s&quot;\r\n\r\n...\r\n&gt;\r\n<\/pre>\n<p>As you can see we (as a receiver) get that same record we (as a sender) set in our DNS, now the recipient can use the p= parameter to get the public key and create <em>RSACryptoServiceProvider <\/em>. It can be later used to verify the signature.<\/p>\n<p>You can <a href=\"\/mail\">download .NET email component here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>DKIM is short for DomainKeys Identified Mail. It is a method for associating a domain name to an email message. It allows a person, role, or organization (domain owner) to claim some responsibility for the message. DKIM adds a digital signature to the email message headers (using DKIM-Signature field), which can be validated by recipients. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[15,18,33,57],"class_list":["post-1008","post","type-post","status-publish","format-standard","hentry","category-mail-dll","tag-c","tag-dkim","tag-email-component","tag-vb-net"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/1008"}],"collection":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/comments?post=1008"}],"version-history":[{"count":6,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/1008\/revisions"}],"predecessor-version":[{"id":4606,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/1008\/revisions\/4606"}],"wp:attachment":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/media?parent=1008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/categories?post=1008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/tags?post=1008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}