The original DKIM specification only allowed RSA signatures. Although there is nothing wrong with RSA, the keys are unfortunately rather large, which causes issues in setting up the DKIM DNS records. The DKIM specification also did not require DKIM validators to support keys larger than 2048 bits, so cryptographic strength is limited.
With the introduction of RFC8463 it has become possible to use DKIM with the Edwards-curve Digital Signature Algorithm (EdDSA). EdDSA is a type of elliptic curve cryptography (ECC) that uses the Curve25519 elliptic curve. Hence, this type of cryptographic signature is commonly referred to as Ed25519.
Compared to a 2048-bit RSA key, Ed25519 has the benefit of having much smaller keys but higher cryptographic strength. This allows for higher strength signatures, without hitting length limitations in DNS records.
In this article we'll explore how to create an Ed25519 key pair using OpenSSL, and how to create an Ed25519 DKIM DNS record from that key pair.
This article is intended for email administrators and developers who want to sign their email with Ed25519 DKIM signatures. We expect that you are already familiar with setting up DKIM signing with RSA.
To verify that your software supports Ed25519 signatures and for implementation details, please refer to the documentation of your MTA or DKIM signing software.
Note that if you use a cloud based email service that supports Ed25519 signing, your cloud email provider should supply the DNS records to set.
A word of caution
Please be aware that Ed25519 DKIM support is currently very limited amongst most email services. Most DKIM signing software does not yet support signing with Ed25519 signatures, and most verifiers (receivers) cannot verify Ed25519 signatures yet.
Never rely on Ed25519 DKIM signatures exclusively. Email signed with Ed25519 DKIM signatures should always include a fallback RSA DKIM signature.
To start, we create a new Ed25519 private key using OpenSSL. Note that unlike RSA, with Ed25519 there are no options such as key length to choose from. An Ed25519 key always has a fixed size of 256 bits.
openssl genpkey -algorithm ed25519 -out dkim_private.pem
We then use OpenSSL again to calculate the public key from the newly created private key.
openssl pkey -in dkim_private.pem -pubout -out dkim_public.pem
The resulting public key will look something like this:
-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEA7x8OfAKmZwqS4ZoWsIozL+2rRvm9DYN1dqdxQGybKuU= -----END PUBLIC KEY-----
Notice that the Ed25519 keys are much smaller than a 2048-bit RSA public key that would normally be used for DKIM. An Ed25519 key is only 256 bits in size, yet its cryptographic strength is comparable to a 4096-bit RSA key.
A DKIM TXT resource record with Ed25519 keys differs from the regular RSA DKIM record as follows:
k(key algorithm) property must be set to
p(public key) property must only contain the BASE64 encoded key, not the entire ASN.1 structure that OpenSSL created.
With RSA, the
p value of the DKIM DNS record is expected to contain an ASN.1 structure with the RSA public key.
This is needed because RSA keys can have various properties such as the key size and the exponent.
With Ed25519 there are no settings, so there is no need for an ASN.1 structure.
When using Ed25519 the
p value in the DKIM DNS record must only contain the BASE64 encoded public key, without an ASN.1 structure.
This makes the record even smaller. So small in fact, that the entire DKIM record can now fit in a single 255 byte DNS
<character-string> structure, which makes fetching the DKIM record a lot more efficient for validators.
This does mean that we need to do a little more work on the command line, as OpenSSL unfortunately does not have an option to output the raw key, it is always wrapped in an ASN.1 structure.
Using the OpenSSL
asn1parse function, we can extract the raw Ed25519 key from the ASN.1 structure in the PEM encoded public key file, and then convert it back to BASE64 format:
openssl asn1parse -in dkim_public.pem -offset 12 -noout -out /dev/stdout | openssl base64
Note for Windows users
When using OpenSSL native under Windows (either in the command prompt, or PowerShell), the OpenSSL piping behavior is problematic, as there is no
/dev/stdoutavailable on Windows environments. As a workaround, first write the raw key data to an intermediate file
pubkey.raw, then load it into the BASE64 encoder from file.
openssl asn1parse -in dkim_public.pem -offset 12 -noout -out pubkey.raw
openssl base64 -in pubkey.raw
The output of this command will be the
p value of your DKIM DNS record. Notice how this value is shorter than the value in
dkim_public.pem generated by OpenSSL, this is because the ASN.1 structure is stripped.
Now we can create our Ed25519 elliptic curve DKIM record. For the public key example earlier in this article, the resulting DKIM record would look like this:
v=DKIM1; k=ed25519; p=7x8OfAKmZwqS4ZoWsIozL+2rRvm9DYN1dqdxQGybKuU=
Now we can immediately see the main benefit of Ed25519 with DKIM: even with the optional whitespace and optional
v=DKIM1 part (yes, it is optional), this record is only 67 characters long, which makes it fit inside a single DNS
<character-string> object with plenty room to spare.
Once you have published the DNS record, you can use the Mailhardener DKIM record validator to validate and inspect the DNS record.
As with any new standard in email, it is expected that it will take some time before Ed25519 validation is a common feature in email validators (the receiving services). As such, it is not recommended to exclusively rely on Ed25519 for DKIM.
The signer (sending email service) should use a dual DKIM signature approach where email is signed with both an Ed25519 signature, and an RSA signature for backwards compatibility.
This means that 2 DKIM DNS records must be created. One containing the Ed25519 key, and one with a fall-back RSA type key. The two DKIM DNS records must use a different selector, as DKIM does not allow multiple DKIM records to exist with the same selector.
The signer (the sending email service) must now add two
DKIM-signature headers to the email: one with
a=rsa-sha*, and one with
i (if set) values in both DKIM signature header must be equal between both signatures.
A properly implemented validator should prefer the signature with
ed25519-sha256 algorithm over the
rsa-sha* algorithm if supported.
The validator should not validate the
rsa-sha* signature if a valid
ed25519-sha256 is found for the same
Legacy validator services that do not support
ed25519-sha256 should ignore that DKIM-signature and fall back to the
Note: with RSA DKIM signatures the SHA1 hashing algorithm could be used.
SHA1 has been proven unsafe and should no longer be used.
When using ed25519 signatures, only SHA256 is allowed to be used, thus the only allowed value for
a in the DKIM header is
Ed25519 DKIM signatures offer a number of benefits for both signers and validators.
We can't rely exclusively on Ed25519 signatures just yet, as it will take time for validators to be updated to support Ed25519 signatures. With implementing Ed25519 you can already benefit from the higher cryptographic strength of Ed25519 DKIM signatures and also help accelerate the adoption of Ed25519 for DKIM.
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.