Index

How to create a DKIM record with OpenSSL

With DKIM, digital signatures are added to email messages, for authorisation of the sender and authentication of the email itself.

To create and validate DKIM signatures a pair of keys known as the public and private key must be created by the signer (the sender). The private key stays at the server or service that sends the email, the public key is published using a DNS TXT record.

In this guide we will explain how to use OpenSSL to create an RSA key pair suitable for DKIM signing.

Note that the key pair is to be created by the sender, so if you use a cloud service such as Gmail, Office365, Mailchimp, Mailgun, etc then you do not need to create DKIM keys. The email service provider will create the keys for you, and give you the value of the DKIM DNS record that you should place in your DNS zone.

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

Update: Besides RSA, it is now also possible to use Ed25519 elliptic curve signatures with DKIM, we published a new guide: how to use DKIM with ed25519.

Generating the private key

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

openssl genrsa -out dkim_private.pem 2048

Please note that the DKIM specification only requires DKIM validators to support RSA keys up to 2048 bit. So although it may be tempting to create a stronger key here, there is no guarantee that a key larger than 2048 bit will be accepted.

The resulting file dkim_private.pem contains the private key that will be used by your email software or library to create the DKIM signature. Please refer to the documentation of your software or library for instructions on how set up DKIM signing. The DKIM signing software requires at least two pieces of information: the private key, and the public key selector. The selector is an address where a validator (a receiver of the email) can find the public key. You can read more about selectors later in this article.

Care must be taken when handling this file, a private key must always stay private. It should only be installed on the server which is responsible for DKIM signing (for example: your SMTP server). The private key must never be shared with anyone else.

Choosing a selector

Since a domain can use multiple DKIM keys (usually one per service), there must be a way for the validator (the receiver) to know which key to use to validate the email. That is why a DKIM signature in an email contains an identification field known as the selector. The selector is an identifier for the DKIM key, it tells the receiver which DNS address to query to find the public key.

The DKIM public key is expected to be found in a DNS record at address [selector]._domainkey.[domain].

You can choose any value as the selector, as long as it is permitted to use as a DNS hostname (that is: all lowercase letters, numbers and hyphens). It is recommend to use the name of the service and some date indicator, so it's easy to remember where this key is used. Examples of selectors can be: google010118, mailchimp2017 or mailserver1

The signer (the email sending software or service that creates the DKIM signature) adds the selector into the DKIM header in the email. The validator (the receiver of the email) uses the selector in combination with the domain name from the sender email address to know where to find the public key.

Example: An email is received with sender address demo@mailhardener.com, the email contains a DKIM signature with selector demo2020. The receiver will perform a DNS query on demo2020._domainkey.mailhardener.com to fetch the public key.

A query on your DNS must result in no more than 1 TXT type record per selector. If you use multiple DKIM keys, then you must choose a unique selector for each key.

Creating the DNS record

A DKIM DNS record is a TXT type DNS record that holds the public key, which corresponds to the private key. Validators (receivers of email) will use this public key to validate the DKIM signature in an email from your domain.

The required format of the DKIM DNS record is pretty straight forward. It is the common key=value; key=value style syntax. Keys and values are separated by an = character, and multiple key/value pairs are separated by a semicolon. Any whitespace is ignored. The full DKIM DNS record format is specified in RFC4871.

In its minimal form, the DKIM DNS record only requires the public key field p to be present, the rest is optional. It's a common misconception that the v=DKIM1 version indicator is required, but as defined in RFC4871, the v field is recommended but not required.

We can use OpenSSL to calculate the corresponding public key from the private key, and format it in BASE64 encoding suitable for use in a DKIM DNS record:

openssl rsa -in dkim_private.pem -pubout -outform der 2>/dev/null | openssl base64 -A

The output of this command is the public key in BASE64 format. This will be the p value of the DKIM DNS record.

In it's minimal form, a DKIM DNS record will look like this:

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

Now that you have generated the keys and chosen a selector, it is time to publish the public in your DNS zone.

The DKIM public key must be placed at [selector]._domainkey.[domain].

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 DNS records.

Here is an example of a DKIM DNS 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, you can use our DKIM record validator to validate that you have correctly set the DKIM DNS record.

Configuring your email software

Now that the selector is chosen and the public key is published in the DKIM DNS record, you can configure your email software to add DKIM signatures using the private key.

This can be done on your SMTP server, or in the software that creates the email. If you are a developer and use a library to send email over SMTP, it is usually possible to create the DKIM signature directly using that library.

Please refer to the documentation of your specific software or software library of choice on how to configure DKIM. The configuration will need at least 2 configuration items: which private key to use, and which selector to use.

If your library or SMTP server (MTA) software does not support DKIM, it is common to use a DKIM proxy.
A DKIM proxy is a program that adds a DKIM signature header to any email it receives, and then forwards the email to a pre-configured SMTP server.

Rotating or revoking keys

Replacing a private/public key pair with a new pair is known as rotating. Removing or otherwise invalidating a key pair is known as revoking.

Rotating can be done for various reasons, such a software or service migration, server maintenance or when the private key is lost. Revoking is commonly done when a key is compromised, or when an email service is no longer used.

If you want to rotate a key, you should never change the existing record, but instead create a new record. Note that a selector must only return one DKIM DNS record, so the new DKIM DNS record must use a different selector.

Revoking a DKIM key pair is done by removing the DKIM DNS record. If you rotate a key, it is recommended to use a transition period (about 1 week is recommended) before revoking the old key. This way you can be 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 validators (receivers) cache DKIM public keys, so 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 to revoke that DKIM DNS record from the DNS zone.

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. Any content longer than 255 characters will result in multiple <character-string> structures inside the DNS resource record. A DNS client combines 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 of multiple <character-string> structures.

Although almost all DNS service providers will automatically split long TXT records 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 long TXT values in Google Cloud DNS due to its many quirks.

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

Further reading

See also

Share your thoughts!

On last thing: If you have questions, comments or thoughts on this article, don't hesitate to shoot us an email.

You can also follow and reach us on Twitter @Mailhardener.

With Mailhardener you can configure, validate and monitor your domain for all aspects of email security. Mailhardener is free to use for a single domain.
Sign up now