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.