Posts Tagged ‘DKIM’

Import certificate, private or public keys (PEM, CER, PFX)

Tuesday, November 22nd, 2011

Encrypted private key, RSA private key in PEM file:

PEM stands for Privacy Enhanced Mail format.

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadEncryptedPrivateKeyFromFile(
   "EncryptedPrivateKey.pem", // "EncryptedRSAPrivateKey.pem"
   "cypher");

This code handles following formats:

PKCS #8 EncryptedPrivateKeyInfo Encrypted Format:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICojAcBgoqhkiG9w0BD .....

Private Key (Traditional SSLeay RSAPrivateKey format) Encrypted:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,24A667C253F8A1B9

mKz .....

You can remove the passphrase from the private key:
openssl rsa -in EncryptedPrivateKey.pem -out PrivateKey.pem

Unencrypted private key in PEM file:

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadPrivateKeyFromFile(
   "PrivateKey.pem");

This code handles following formats:

PKCS #8 PrivateKeyInfo Unencrypted:

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0B ......

Private Key (Traditional SSLeay RSAPrivateKey format) Unencrypted:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCcHVm .....

Public key in PEM file:

PemReader pem = new PemReader();
RSACryptoServiceProvider rsa = pem.ReadPublicKeyFromFile(
   "PublicKey.pem")

This code handles following formats:

Public Key (SubjecPublicKeyInfo):

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEB .....

Certificate/private key in PFX file:

X509Certificate2 certificate  = new X509Certificate2(
   "certificate.pfx",
   "",
   X509KeyStorageFlags.PersistKeySet)

if (certificate.HasPrivateKey)
{
  using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certificate.PrivateKey)
  {
  }
}

Certificate in PEM/CER file

Note: The private key is never stored in a .pem/.cer file.

X509Certificate2 certificate = new X509Certificate2(
   "certificate.cer");

-or-

PemReader pem = new PemReader();
X509Certificate2 certificate = pem.ReadCertificateFromFile(
   "certificate.cer");

This code handles following formats:


-----BEGIN CERTIFICATE-----
MIIFsTCCA5mgAwIBAgIKYQ .....

Sign emails with DKIM

Tuesday, July 27th, 2010

DKIM is short for DomainKeys Identified Mail.

Adding a signature looks like this:

// C#

var certificate = new X509Certificate2("Test.pfx");
var rsa = (RSACryptoServiceProvider)certificate.PrivateKey;

IMail email = Mail
       .Text("text")
       .From("alice@mail.com")
       .To("bob@mail.com")
       .Subject("subject")
       .DKIMSign(rsa, "brisbane", "example.com")
       .Create();
' VB.NET

Dim certificate = New X509Certificate2("Test.pfx")
Dim rsa = DirectCast(certificate.PrivateKey, RSACryptoServiceProvider)

Dim email As IMail = Mail _
		.Text("text") _
		.From("alice@mail.com") _
		.[To]("bob@mail.com") _
		.Subject("subject") _
		.DKIMSign(rsa, "brisbane", "example.com") _
		.Create()

So what you need is RSACryptoServiceProvider with your private key, and two strings: selector and domain.

Basically how this works is the recipient of the email queries the DNS server for TXT record for selector._domainkey.domain (in our sample it is: “brisbane._domainkey.example.com”) to get the public key and validate the signature.

You can use nslookup to get the public key for a domain:

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:UsersPawel>nslookup
Default Server:  UnKnown
Address:  192.168.0.1

> set type=TXT
> gamma._domainkey.gmail.com
Server:  UnKnown
Address:  192.168.0.1

Non-authoritative answer:
gamma._domainkey.gmail.com      text =

        "k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIhyR3oItOy22ZOaBrI
Ve9m/iME3RqOJeasANSpg2YTHTYV+Xtp4xwf5gTjCmHQEMOs0qYu0FYiNQPQogJ2t0Mfx9zNu06rfRBD
jiIU9tpx2T+NGlWZ8qhbiLo5By8apJavLyqTLavyPSrvsx0B3YzC63T4Age2CDqZYA+OwSMWQIDAQAB"

gmail.com       nameserver = ns1.google.com
gmail.com       nameserver = ns4.google.com
gmail.com       nameserver = ns3.google.com
gmail.com       nameserver = ns2.google.com
ns1.google.com  internet address = 216.239.32.10
ns2.google.com  internet address = 216.239.34.10
ns3.google.com  internet address = 216.239.36.10
ns4.google.com  internet address = 216.239.38.10
>

But don’t worry as Mail.dll will make this DNS query for you.

Validating (including DNS query for public key) is simple:

// C#

IMail email = new MailBuilder()
    .CreateFromEmlFile("signed_gamma.gmail.eml");
bool isValid = email.CheckDKIMSignature();
' VB.NET

Dim email As IMail = New MailBuilder() _
    .CreateFromEmlFile("signed_gamma.gmail.eml")
Dim isValid As Boolean = email.CheckDKIMSignature()

You can download Mail.dll .NET email component here.