With DKIM, digital signatures are added to email messages, for authorization 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, Microsoft 365, 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.
You will notice that in this article, we show you how to generate 2048 bit RSA keys. You may be tempted to go with a larger key size of 4096 bits yourself, because more bits is more secure. And though it is true that a bigger key will give more cryptographic strength, a 4096-bit RSA key can cause compatibility issues with DKIM and is therefore not recommended to use. The recommended RSA key size for DKIM is 2048 bits.
The main reason for this is that, unfortunately, there are still many DKIM implementations currently deployed that do not support 4096-bit RSA keys, despite the fact that this has been required since 2018 with the introduction of rfc8301.
Another problem with 4096-bit RSA keys is that the public part will exceed the maximum size of a DNS packet over UDP (which is the default). This will cause the DNS to return a 'truncation' response, forcing the DNS client to switch to TCP instead. Not every DNS implementation may support DNS over TCP.
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
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.
Since a domain can use multiple DKIM keys (one or more 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 recommended 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.
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 ec -in dkim_private.pem -pubout -outform der | openssl base64 -A
Note that we use
openssl ec
here, and notopenssl rsa
. Theec
command should accept both ECC and RSA keys, whereas thersa
command doesn't. If your OpenSSL client does not support elliptic curve cryptography, then replaceec
withrsa
. Many thanks to Wolfgang Kraft for this tip!
The output of this command is the public key in BASE64 format. This will be the p
value of the DKIM DNS record.
In its 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 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.
Now that you have generated the keys and chosen a selector, it is time to publish the public key 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.
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.
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 realize 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.
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.
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 X @Mailhardener.