In Exchange Online DKIM is a built-in service, but on an on-prem Exchange 2019 deployment we need a 3rd party application to add this functionality to our Exchange infrastructure.
In this guide we use Stefan Profanter's excellent dkim-exchange application for this purpose, which is available here: https://github.com/Pro/dkim-exchange/releases/latest
After installing the program, we open Configuration.DkimSigner.exe
and click on the "Install" button, or download the installer straight from https://codeload.github.com/Pro/dkim-exchange/legacy.zip/v***
After installation finished, open the configurator.
C:\Program Files\Exchange DkimSigner\Configuration.DkimSigner.exe
Click on the "Configure" button and move the DkimSigner agent to the very bottom of the list.
Under the DKIM settings tab select relaxed canonicalization as Exchange tend to add, remove and change whitespaces (spaces, tabs, new lines) when processing and submitting messages. This is a problem, as DKIM creates a hash signature of the original message body and header, then when received, the recipient server will create those hashes too and compares the two versions. They need to match.
Simple canonicalization requires the body and header of the messages to be identical when comparing the original message and the received version. Relaxed canonicalization gives the transport agents more flexibility in changing messages, it replaces all whitespaces with a single space character, converts all characters to lowercase, removes heading and trailing whitespaces, etc.
On the "Domain Settings" tab we add our domain name, the DKIM selector name will be selector1.
The private and public keys will be generated. The server encrypts the hashes with the private key, the clients will use the public key to decrypt that hash. This proves authenticity as only the server can generate this encrypted key, if someone modified the message in transit they could re-generate the hashes of the new body and header, but the cannot encrypt the hash like the server do.
Publish the selector DNS record for DKIM
The public key is published in the p= part of the DNS record that we add the domain public zone file, in our example at GoDaddy.
Restart the service
How it works
John Doe from Always Hot Café sends me a message to email@example.com. The header of the received email contains a section called DKIM-Signature. The s= part tells my client that the dkim selector is selector1, that means the client will check the selector1._domainkey.alwayshotcafe.com TXT record, which contains the public key with which the client is able to decrypt the two hashes under the b= and bh= parts.
Received-SPF: Pass (protection.outlook.com: domain of alwayshotcafe.com
designates 126.96.36.199 as permitted sender)
Received: from MAIL.AlwaysHotCafe.com (188.8.131.52) by
LO2GBR01FT003.mail.protection.outlook.com (10.152.42.89) with Microsoft SMTP
Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
15.20.2921.25 via Frontend Transport; Sat, 18 Apr 2020 09:48:28 +0000
DKIM-Signature: v=1; a=rsa-sha256; d=alwayshotcafe.com; s=selector1;
c=relaxed/relaxed; t=1587203307; h=from:subject:to:date:message-id;
Received: from MAIL.AlwaysHotCafe.com (10.0.1.2) by MAIL.AlwaysHotCafe.com
(10.0.1.2) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.397.3; Sat, 18 Apr 2020
After having the original hashes, the client goes through the same hashing process, using the algorithm specified it the a= part.
If the newly generated and the earlier decrypted hashes match, the DKIM test passes.