Index

How to create a DKIM record with OpenSSL

The popular open source OpenSSL toolkit can be used to generate key pairs suitable for DKIM.

DKIM keys are usually created by the service that sends email, such as Gmail, Mailgun, Mailchimp, etc. But if you run your own email server you can use this guide to create a DKIM record so you can cryptographically sign your email.

If you are a developer and you need to send email from your code, it's good practice to sign the email with DKIM before sending it. Most popular email libraries will have support to create the DKIM signature, but for that to work you must supply your own key. This guide will teach you how it's done.

Definitions

To refresh your memory a bit, we'll lay out the terms used in this guide:

If you are new to DKIM, we recommend reading our main article about DKIM first.

Generating the key pair

To start, use openssl to create a new private key. The key we are generating here is a 2048 bit key.

openssl genrsa -out dkim_private.key 2048

Now that we have created the key, we use openssl to derive the public part of the key:

openssl rsa -in dkim_private.key -pubout -outform PEM -out dkim_public.key

The resulting public key will look something like this:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArPdDS3zq7wsDtXR/dP9Q
Vaay1m0QpksDulGfqZ1H4Cnd4mT+eRZbnSfpd0BY6iuxAosJGtEkbeZkZslMkGb1
ocKkN/EofzGEIC4QV/y1qyujUQ6htFcRk64vN8PB0hJ08lZyAgS1VGzUI7xXxV0/
uB4WQlb1M+v0ZF2TkXPFfF5lPyh3GDFyWQnMMnfv+IMxecxmanh2tmRhNi1AbBwB
FakM9PHBsrkgeHDdpw4vJY3D+IcrdpJhHD2FhlUM/bX6um/1tTwlo2KTro8o/QwF
5B0EY19DOuVnK6Xl7OGCt57eZMtflMkaw65lKrLG4F1rwqF/SlchoTbLDP5EQ4Uc
5QIDAQAB
-----END PUBLIC KEY-----

The -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- parts are x.509 PEM format headers, the are not needed for the DKIM record.

Creating the record

A DKIM record is a TXT type DNS record, the format is defined in RFC4871. In it's minimal form, the DKIM record only requires the public key p to be present, the rest is optional. It's a common misconception the the v=DKIM1 version indicator is required, but as defined in RFC4871, the field is RECOMMENDED but not REQUIRED.

A DKIM record uses the common key=value style syntax. Key/value pairs are separated by a semicolon. Any whitespace is ignored.

The minimal form of the DKIM record in this example would be:

p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArPdDS3zq7wsDtXR/dP9QVaay1m0QpksDulGfqZ1H4Cnd4mT+eRZbnSfpd0BY6iuxAosJGtEkbeZkZslMkGb1ocKkN/EofzGEIC4QV/y1qyujUQ6htFcRk64vN8PB0hJ08lZyAgS1VGzUI7xXxV0/uB4WQlb1M+v0ZF2TkXPFfF5lPyh3GDFyWQnMMnfv+IMxecxmanh2tmRhNi1AbBwBFakM9PHBsrkgeHDdpw4vJY3D+IcrdpJhHD2FhlUM/bX6um/1tTwlo2KTro8o/QwF5B0EY19DOuVnK6Xl7OGCt57eZMtflMkaw65lKrLG4F1rwqF/SlchoTbLDP5EQ4Uc5QIDAQAB

To give the record a little bit more context, we do recommend placing the version field, like so

v=DKIM1; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArPdDS3zq7wsDtXR/dP9QVaay1m0QpksDulGfqZ1H4Cnd4mT+eRZbnSfpd0BY6iuxAosJGtEkbeZkZslMkGb1ocKkN/EofzGEIC4QV/y1qyujUQ6htFcRk64vN8PB0hJ08lZyAgS1VGzUI7xXxV0/uB4WQlb1M+v0ZF2TkXPFfF5lPyh3GDFyWQnMMnfv+IMxecxmanh2tmRhNi1AbBwBFakM9PHBsrkgeHDdpw4vJY3D+IcrdpJhHD2FhlUM/bX6um/1tTwlo2KTro8o/QwF5B0EY19DOuVnK6Xl7OGCt57eZMtflMkaw65lKrLG4F1rwqF/SlchoTbLDP5EQ4Uc5QIDAQAB

The version field will make it easier to remember what the record is for. If you do place the version field, it should be at the very beginning of the record.

Placing the record in your DNS zone

A DKIM record is must be placed in at address [selector]._domainkey.[domain]. The selector is an identifier for the DKIM key. You can choose any selector, but we recommend using the name of the service and some date indicator. Examples of selectors can be: google010118, mailchimp2017 or mailserver1

If you need more than 1 DKIM key, then choose a unique selector per key. A query on your DNS may only result in 1 TXT type record per selector.

DKIM keys are not meant to ever change, so you can use a long time-to-live (TTL) value for the record. A TTL of 1 day (86400 seconds) or more is not uncommon for DKIM records.

Here is an example of a DKIM record in a dig output:

google._domainkey.mailhardener.com. 86400 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgAF0AKrnAY2oscOh7jlBBPJDHgWO/HR/TxPr18yG6uFs3jVLkz1qZpI0QJX90aVnpPiu1C+6MZzUwzYYY/f8g8rVGxwj2D/anjih4sKUFmun2IluFiS93RcPZXYWNXor4gALdsdAVB7ak4/30l0uVAU3OEwFX77yWNT6BDSiobfpKMDG4TV4iZiohOlc1gHHX" "HYbLbcQ1uM9CLPkuqHKQkudLjvAbvl0eqDtAzThAahsmhl5Lc7Qru1SJShv47RxzIxShBL6MGTxEGiIR09244oQf++CmKCT8TPxptT/Y6mrLO5+t//dlvSVLsrKhF6xqZWwSOL0pskJiDdqDAxDGQIDAQAB"

Note that dig added the quotes around the record text for readability, these quotes are not actually in the record payload.

Examples of DNS records usually include quotes, because that is how dig formats them, but you must not add the quotes when setting the DNS record at your DNS service provider.

To add to the confusion: some DNS service providers (most notably Google Cloud DNS) require quotes in their interface, where others don't. Unintended double quoting is a commonly made mistake.

When setting DNS records, always double check your changes with dig. For DKIM records, you can use our DKIM record validator

Rotating or revoking keys

If you want to rotate (change) a key, you should not change the existing record. Always create a new DKIM record with a different selector for the new key. You should remove the old DKIM record after a transition period (about 1 week is recommended) to make sure that any delayed email delivery will still pass DKIM validation with the old key.

If you have indication that the old key was compromised, you can use a shorter (or no) transition period, but do realise this may prevent any delayed emails to be delivered.

Note that due to caching, it may take some time for receivers to notice a key is removed.

If a DKIM key is no longer in use, it is recommended remove that DKIM record from the DNS.

DNS length limitations

Internally, a DNS TXT resource record uses a data structure known as a <character-string> which has a length limit of 255 characters. To overcome this length limitation the DNS standard specifies that a TXT resource record can hold multiple <character-string> structures. The DNS client must combine the <character-string> structures to reconstruct the original string.

A DKIM resource record will almost always exceed 255 characters in length, so it will consist out of multiple <character-string> structures.

Although almost all DNS service providers will split long TXT records automatically into 255 character parts for you, some DNS service providers require you to do this by hand. We even devoted an entire blog post on how to enter TXT values in Google Cloud DNS due to its many quirks.

If your DNS service provider requires you to split the DKIM record manually you can use our DNS record splitter to do this.

Further reading

See also