Verify message integrity with DKIM
DomainKeys Identified Mail (DKIM) provides a domain-based email authentication protocol that helps identify legitimate email messages. DKIM provides the second factor for domain authentication.
To activate DKIM, a domain owner adds a DKIM record as a DNS TXT record on sending domain. This TXT record contains instructions for verifying a message using public-key cryptography. When sending email with DKIM turned on, the sending server signs the messages with a private key.
Limitations of DKIM
The scope of DKIM has limits. It doesn't verify content, the sending email server, or the message sender. Nor does it instruct the receiver how to route the message or report failed checks. It verifies message integrity.
To generate the comparison values in a DKIM-Signature, the sending email server standardizes both headers and body content. This process is called canonicalization. DKIM follows the Internet Message Format format. Given this standard format, an email message can still undergo some mild modifications in transit. You can choose the level of tolerance you have for these changes as they get authenticated.
- If you want to accept common modifications, choose
relaxed. - If you don't want to tolerate any changes, choose
simple. - You can set this value for both the header and body independently, with the header listed first, then a forward slash (
/), then the body. - This value defaults to
simple/simple.
This results in accepted combinations of simple/simple, simple/relaxed, relaxed/simple, and relaxed/relaxed. If you only provide one value, like relaxed, that value applies to the header. The body gets set to simple and the complete value becomes relaxed/simple.
The service that generates your DKIM signatures sets the method, or algorithm, applied to the header and body content.
- On email servers that you manage, you set the canonicalization value in the DKIM configuration file.
- Most large-scale email servers set their value to
relaxed/relaxed. - Twilio SendGrid sets this value to
relaxed/simple.
To learn how canonicalization changes email message formatting, see Canonicalization.
Comparing two versions of a large value has inherent difficulties. No method can compare an entire single object, like an email message, at two points in time: when one party sent it and when the intended party received it. To compare a single file from two points in time, computer systems use a digital fingerprint of the object called a hash. To create a hash, you use an algorithm that runs mathematical calculations on the data and returns a 256 alphanumeric string. Hashing describes the calculation that creates the hash.
With DKIM, the header and the body content get hashed and the recipient email server compares hashes of the original objects, not the objects themselves.
To protect the data on disk or in transit requires encryption. The data gets transformed into a format that only certain parties can decode. Public key encryption involves a pair of keys: a public key and a private key. The private key transforms, or encodes or encrypts, the data. The party that encrypts the data keeps this key a secret. The public key decodes or decrypts the encrypted data back into its original form. The public key can be widely distributed and used to decrypt data.
With DKIM, the sending email server encrypts the hashed value with its private key. The DKIM DNS TXT resource record includes the public key, which can decrypt the DKIM-Signature and prove message data integrity.
To convert binary data into text characters, email servers use Base64 encoding. This converts 8-bit (2^8) representations of data into 6-bit (2^6) representations of data. With this encoding, you only need 64 characters to represent any data, hence the name Base64. In practice, this means that every three bytes, or 24 bits, of data gets converted into four characters. This encoding allows sending of any type of data including images and attachments.
To ensure transmission of all types of data and not just text, DKIM encodes the data with Base64.
DKIM implementation requires creating the instructions and public key stored on the sender's domain and configuring any DKIM settings on the email server.
With DKIM, receiving email servers check the integrity of incoming email messages in the following process:
- Identify or install a DKIM processor on your sending email server.
- Configure the basic settings for the DKIM processor, like the canonical algorithm.
- Generate a DKIM key pair on your sending email server. If prompted, use the following parameters:
- selector: A unique identifier for the key, like a subdomain or a hostname for a server.
- key size: The cryptographic strength or size of the key in bits, either
1024or2048.
- Copy the public key.
- Create a
TXTDNS record.- Set the record label to
<selector>._domainkey.<domain>. - Set the record value to the signature, outlined in the DKIM record format.
- Set the record label to
- When sending an email message, your sending message transfer agent (MTA) creates your
DKIM-Signatureand adds it to the message.
To implement DKIM for your account on Twilio SendGrid, see the Domain Authentication guide.
An DKIM record resides as the value of a DNS TXT labeled <selector>._domainkey.<domain> with a value that resembles the following:
k=rsa;t=s;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDmzRmJRQxLEuyYiyMg4suA2SyMwR5MGHpP9dNT1hRiwUd/mZp1ro7kIDTKS8ttkI6z6eTRW9e9dDOxzSxNuXmume60Cjbu08gOyhPG3GfWdg7QkdN6kR4V75MFlw624VY35DaXBvnlTJTgRg/EW72O1DiYVThkyCgpSYS8nmEQIDAQAB
The TXT record value must adhere to the following standards:
- It must follow RFC 1035 3.3.14 format for DNS records.
- It can't exceed 512 bytes.
To improve your email deliverability, Twilio turns on DKIM for all email messages. This provides you with a custom DKIM record. When you configuring an authenticated domain, choose automated or manual security.
These differ in who updates to DNS records and the DKIM signature after making changes that impact deliverability. This could include adding another dedicated sending IP address or granting a subdomain permission to send email messages.
- Automated security grants Twilio permission to make updates on your behalf.
- Manual security leaves updates to your best efforts.
When you turn on automated security, Twilio generates three canonical name (CNAME) resource records. With these records set, Twilio SendGrid manages your DKIM and SPF records. Whenever you change an account setting that could impact your deliverability, like adding a dedicated IP address, Twilio SendGrid updates your DNS settings and your DKIM signature.
Twilio uses multiple selectors (s1 and s2, by default) interchangeably and rotates them when necessary. Twilio only activates one selector for generating DKIM signatures at any given time.
Example of DNS records for DKIM with Automated Security ON
| DNS record | Type | Record value |
|---|---|---|
subdomain.example.com. | CNAME | uXXXXXXX.wlXXX.sendgrid.net |
s1._domainkey.example.com. | CNAME | s1.domainkey.uXXX.wlXXX.sendgrid.net. |
s2._domainkey.example.com. | CNAME | s2.domainkey.uXXX.wlXXX.sendgrid.net. |
To verify the authenticity of a message's signature, receiving mail servers parse the DKIM-Signature email header.
With DKIM turned on, the sending email server adds an DKIM-Signature metadata header to each email message. This header resembles the following example:
1DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=brisbane;2c=relaxed/simple; q=dns/txt; i=foo@eng.example.net;3t=1117574938; x=1118006938; l=200;4h=from:to:subject:date:keywords:keywords;5z=From:foo@eng.example.net|To:joe@example.com|6Subject:demo=20run|Date:July=205,=202005=203:44:08=20PM=20-0700;7bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;8b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR
With DKIM, receiving email servers check the integrity of incoming email messages in the following process:
- The receiving server checks the format of the
DKIM-Signatureheader. If theDKIM-Signaturemeets any of the following conditions, the check fails.- Signature misses one of the required tags:
v=,a=,b=,bh=,d=,h=, ands=. - The domain in the
i=tag doesn't match the complete or parent domain in thed=tag. - The
h=tag doesn't include theFromheader.
- Signature misses one of the required tags:
- The receiving server sends a request to the sending domain's DNS server, based on the
s=andd=tags of the signature, following the method in theq=tag. Theq=tag only accepts a value ofdns/txt, which translates to check theTXTrecord in theDNSserver.- If the query fails to respond, the recipient can try again later.
- If the query responds that the DKIM record doesn't exist, the check fails.
- This domain's DNS server returns the DKIM record to the receiving server. If the DKIM record meets any of the following conditions, the check fails.
- The DKIM record doesn't follow the DKIM specification.
- The
h=tag in the DKIM record doesn't include the value in thea=tag of the signature. - The DKIM record doesn't include a public key in the
p=tag. - The
k=tag in the DKIM record doesn't match thea=tag of the signature.
- The receiving server prepares comparison values using the tags from the signature.
- Creates a standard version of the message body using the canonicalization algorithm from the
c=tag. - Truncates the message body length to the value of the
l=tag. - Applies the hash algorithm from the
a=tag on the truncated, canonicalized message body. The hash algorithm defaults to SHA256. - Converts the 256-character body hash using Base64.
- Compares the resulting value to the
bh=tag value. If the values don't match, the check fails. - Applies hash algorithm from the
a=tag on the headers from theh=tag and their values, using the canonicalization algorithm from thec=tag, and theDKIM-Signatureheader itself without itsb=tag. As theDKIM-Signatureheader includes thebh=tag, the body hash gets included. - Applies the encryption algorithm from the
a=tag to the combination of the headers and their values and theDKIM-Signatureheader. The encryption algorithm defaults to RSA, but could be Ed25519. - Converts the 256-character encrypted header hash using Base64.
- Compares the resulting value to the
b=tag. If the values don't match, the check fails.
- Creates a standard version of the message body using the canonicalization algorithm from the
- The next step depends on the check result which only have one of two outcomes:
- The check passes. The receiving email server delivers the message to the specified recipient.
- The check fails. The receiving email server rejects the message and processes it according to the DMARC policy or the inbox provider's filtering rules.