Using DomainKeys Identified Mail (DKIM) Signatures

March 26, 2020 Contributors

DomainKeys Identified Mail (DKIM) is a mechanism that allows verification of the source and contents of email messages. Using DKIM, sending domains can include a cryptographic signature in outgoing email messages. A message’s signature may be verified by any (or all) MTAs during transit and by the Mail User Agent (MUA) upon delivery. A verified signature indicates the message was sent by the sending domain and the message was not altered in transit. A signature that fails verification indicates the message may have been altered during transit or that the sender is fraudulently using the sending domain name. Unsigned messages contain no guarantee about the sending domain or integrity of the message contents. For more information about DKIM, see draft-ietf-dkim-base-00.

To determine subsequent handling of incoming email messages, service providers may use the success/failure of DKIM signature verification or the lack of a DKIM signature. The provider can drop invalid messages without impacting the final recipient, exposing the results of DKIM verification directly to the recipient, or exposing the lack of a signature directly to the recipient. Additionally, service providers may use signature verification as the basis for persistent reputation profiles to support anti-spam policy systems or to share with other service providers.

“DKIM schematic” gives a graphical view of how DKIM works.

For Sending Servers

  1. Set up

    The domain owner (typically the team running the email systems within a company or service provider) generates a public/private key pair to use for signing all outgoing messages (multiple key pairs are allowed). The public key is published in DNS, and the private key is made available to their DKIM-enabled outbound email servers. This is step "A" in the diagram to the right.

  2. Signing

    When each email is sent by an authorized end-user within the domain, the DKIM-enabled email system automatically uses the stored private key to generate a digital signature of the message. This signature is included in a DKIM-Signature header and prepended to the email. The email is then sent on to the recipient’s mail server. This is step "B" in the diagram to the right.

For Receiving Servers

  1. Preparation

    The DKIM-enabled receiving email system extracts and parses the message’s DKIM-Signature header. The signing domain asserted by the header is used to fetch the signer’s public key from DNS. This is step "C" in the diagram to the right.

  2. Verification

    The signer’s public key is then used by the receiving mail system to verify that the signature contained in the DKIM-Signature header was generated by the sending domain’s private key. This proves that the email was truly sent by, and with the permission of, the claimed sending domain. It also provides that all the headers signed by the sending domain and the message body were not altered during transit.

  3. Delivery

    The receiving email system uses the outcome of signature verification along with other local policies and tests to determine the disposition of the message. If local policy does not prohibit delivery, the message is passed to the user’s inbox. Optionally, the email recipient may be informed of the results of the signature verification. This is step "D" in the diagram on the right.

DKIM Signing

Enabling DKIM signing in Momentum is a two-step process:

  1. Generate public and private keys for each signing domain and create the DKIM public key DNS records for those domains.

  2. Configure Momentum to conditionally attach DKIM signatures to emails that are submitted into the MTA.

    • Load the opendkim module. For details, see “opendkim – Open Source DKIM”.

    • Configure the opendkim module to sign messages or write policy to do so at runtime using Lua functions. For details, see “Lua Functions”.

    • Set the opendkim_sign option to true in the appropriate scope to enable DKIM signing on a global, per domain, per binding, or per binding-per domain basis. For details, see opendkim_sign.

To control how OpenDKIM signing statistics are recorded, see signing_stats. The console command signing_stats is used to examine signing statistics and signing_stats reset resets statistics.

Generating DKIM Keys

The OpenSSL cryptography toolkit is used to generate RSA keys for DKIM. As an example, the following openssl commands are used to generate public and private keys for the domain example.com with a selector called dkim1024. Typically, the directory /opt/msys/ecelerity/etc/conf/dkim is used for key storage.

# mkdir -p /opt/msys/ecelerity/etc/conf/dkim/example.com
# openssl genrsa -out /opt/msys/ecelerity/etc/conf/dkim/example.com/dkim1024.key 1024
# openssl rsa -in /opt/msys/ecelerity/etc/conf/dkim/example.com/dkim1024.key \
        -out /opt/msys/ecelerity/etc/conf/dkim/example.com/dkim1024.pub -pubout -outform PEM

All DKIM verification implementations must support key sizes of 512, 768, 1024, 1536, and 2048 bits. A signer may choose to sign messages using any of these sizes and may use a different size for different selectors. Larger key sizes provide greater security but impose higher CPU costs during message signing and verification.

Warning

Note that Google requires all senders to sign with a 1024 bit or greater DKIM key size.

The resulting public key should look similar to:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrZXNwzXOk0mRqPcgSUOnmVHro
rg/BZHybpiBoDS/g6IaMjmVwaQf2E72x9yDBTgiUBtTCqydQRZJ3EbfYfvo+WAHq
2yz6HKR0XCwMDSE2S3brVe7mbV/GPEvnCuFPPEVjbfL4w0tEAd8Seb5h07uVQqy1
Q7jIOnF5fG9AQNd1UQIDAQAB
-----END PUBLIC KEY-----

Once the public and private keys have been generated, create a DNS text record for dkim1024._domainkey.example.com. The DNS record contains several DKIM "tag=value" pairs and should be similiar to the record shown below:

dkim1024._domainkey.example.com. 86400 IN TXT
"v=DKIM1; k=rsa; h=sha256; t=y; p=MHww...QAB"

DKIM DNS text record tags are defined below (do not include the quotes below when including a tag value in the DNS text record):

v=

DKIM key record version. The value of this tag must be set to "DKIM1".

k=

Key type. This tag defines the syntax and semantics of the p= tag value. Currently, this tag should have the value "rsa".

h=

Hash algorithm. Currently, this tag should have the value "sha1" or "sha256".

t=

Flags. The only value currently defined is "y". If specified, this tag indicates the signing domain is testing DKIM.

p=

DKIM public key value generated as described above.

s=

Service Type. If specified, this tag should be set to "*" or "email" which represents all service types or the email service type. Currently, "email" is the only service using this key.

n=

Notes. If specified, the value of this tag is quoted-printable text used as a note to anyone reading the DNS text record. The tag is not interpreted by DKIM verification and should be used sparingly because of space limitations of the DNS text record.