Versenden von E-Mails mit DKIM mit .NET und MailKit

Wer heute automatisierte E-Mails versenden will, die nicht unbedingt in jedem Spam-Filter hängen bleiben sollen, der kommt kaum an DKIM vorbei.

DKIM - DomainKeys Identified Mail - ist ein Mechanismus zur Validierung von E-Mail-Absendern; primär über DNS Einträge.

Mit Hilfe eine DNS-TXT Eintrags wird vereinfacht gesagt ein Public-Key bekannt gegeben, den der E-Mail-Empfänger verwenden kann, um den Ursprung einer E-Mail validieren zu können - wozu die E-Mail Nachricht mit Hilfe eines Private Keys eine Signatur erhält.

Mehr über die prinzipelle Funktionsweise auf Wikipedia .

Generierung der Keys

Für DKIM können selbst erstellte Schlüsselpaare verwendet werden; dazu ist kein gekauftes Zertifikat notwendig.

Dank des OpenSSL-Tools ist dies mit zwei einfachen Befehlen umsetzbar:

Erstellung des privaten Schlüssels für das Signieren der E-Mail:

1openssl genrsa -out beispiel.dkim.private 1024

Mit Hilfe des privaten Schlüssels kann nun ein öffentlicher Schlüssel erzeugt werden, der im DNS bekannt gegeben wird:

1openssl rsa -in beispiel.dkim.private -out beispiel.dkim.public -pubout -outform PEM

Setzen des DNS Eintrags

Mit Hilfe des DNS-Eintrags validiert der E-Mail Empfänger die Signatur.

Der Inhalte des öffentlichen Schlüssels - ohne den Header, Footer oder Leerzeichen - kommt nun in folgendes DNS-Format:

v=DKIM1;k=rsa;t=y;p=Undzwn/n2ndsk……UZnbhudnz=;

Der Inhalt de p-Parameters muss der Inhalt aus dem öffentlichen Schlüssel entsprechen.

Der Name des TXT-Eintrags lautet beispielselektor2021._domainkey wobei beispielselektor2021 ein Platzhalter ist, denn einer Domain können prinzipiell viele Domain Keys hinterlegt werden, sodass man jeden E-Mail Ausgang mit eigenen Schlüsseln konfigurieren kann. Der Selektor wird dabei beim Erstellen der Signatur mit in die E-Mail gepackt, sodass der E-Mail Empfänger weiß, welcher der zugehörige Eintrag ist.

Da jeder Domain-Anbieter eine andere Oberfläche mit sich bringt, wie ein TXT-Eintrag zu setzen ist, überspringe ich diesen Part.

Signieren der E-Mail mit MimeKit

Anders als mit .NET Boardmitteln, die keine direkte Möglichkeit bieten E-Mails mit DKIM zu signrieren, bietet das MimeKit entsprechende Unterstützung an.

Hierzu erzeugen wir mit der Partnerbibliothek MimeKit entsprechend eine E-Mail, setzen Absender und Empfänger sowie den Inhalt - und signieren am Schluss die E-Mail.

 1MimeMessage emailMessage = new(.....);
 2{
 3    // set from
 4    // set to
 5    // set body
 6    // set attachments
 7}
 8string pk = $"-----BEGIN RSA PRIVATE KEY-----\r\n{PrivateKeyString}\r\n-----END RSA PRIVATE KEY-----";
 9MemoryStream stream = new(Encoding.UTF8.GetBytes(pk));
10{
11    stream.Position = 0;
12}
13
14// Erzeugung des Signers mit dem privaten Schlüssel; auch das Lesen einer Datei selbst ist als Übergabeparameter möglich!
15DkimSigner dkimSigner = new DkimSigner(stream, "meinedomain.de", "beispielselektor2021");
16
17// Welche Elemente der Mail sollen mit signiert werden?
18HeaderId[] dkimSignHeaders = { HeaderId.From, HeaderId.To, HeaderId.Subject, HeaderId.Date, HeaderId.MessageId };
19
20// Signieren der Mails
21emailMessage.Body.Prepare(EncodingConstraint.SevenBit);
22dkimSigner.Sign(FormatOptions.Default, emailMessage, dkimSignHeaders);
23
24// Versenden
25smtpClient.SendAsync(emailMessage....);

Das Signieren muss unbedingt am Schluss passieren, da ansonsten entsprechend sich die Inhalte nach der Signatur verändern und die Signatur ungültig wird. Ebenso ist notwendig, dass der Inhalte der Mail - also der Body - durch Prepare() das entsprechende Encoding erhält; fehlt das, ist auch hier die Signatur am Ende ungültig.

Testen und Validieren der Signatur

Es gibt viele verschiedene Tools, die eine DKIM-Validierung anbieten; wirklich empfehlen kann ich aber im Endeffekt nur zwei Tools:

  • Microsoft Outlook kann mit Hilfe des MHA-Addins entsprechende Informationen zu E-Mail Headern anzeigen.
  • Mit Hilfe des Services https://dkimvalidator.com/ kann eine Test-E-Mail versendet werden, die entsprechend analyisiert wird

Outlook MHA:

Der Message Header Inilizer sollte - bei einer korrekten Implementierung von DKIM - folgenden Header-Ausschnitt anzeigen

1DKIM-Signature: v=1; a=rsa-sha256; d=meinedomain.de; s=1und1; c=simple/simple;
2	t=1610929057; h=from:to:subject:date:message-id;
3	bh=IR0r/61rl3Xcv7EAYlNJVNAgqOpheEklTFjbFnFyGIU=;
4	b=OXRyC6ZwDAWTVhKzmHiI0gURspIbw5xNCyzYo5D45iqcy1F5l9UljlGMU38lt4Sy3JLlAn5k2PX
5	/DIFDnmRDaBnw+hVHdlwDBC9FWJawZyyVaYzyIpQ3AG+52g8LuQ+SCqIHogFW/IkYnsNajOSVhbRZ
6	G/qQ2wnZoM0tWpDu2RA=
71705

Dies bestägtigt, dass Signatur über das MimeKit erfolgt ist.

Ein weitrer Header-Eintrag bestätigt darüber hinaus, ob die Signatur selbst gültig ist. Dies ist der Authentication-Results Header, in dem allgemeine Validierungen erfolgen; darunter auch entsprechend der DKIM-Eintrag dkim=test (signature was verified) was uns die Information gibt, dass die Validierung erfolgt und gültig ist.

1Authentication-Results: spf=pass (sender IP is xxx)
2 smtp.mailfrom=meinedomain.de; meinedomain.com; dkim=test (signature was
3 verified) header.d=meinedomain.de;zieldomain.com; dmarc=pass action=none
4 header.from=meinedomain.de;compauth=pass reason=100

Fehlersuche

Sollte die die Validierung nicht erfolgreich sein, so ist eine Validierung gar nicht so einfach.

Zunächst muss natürlich nachgeschaut werden, ob der entsprechende Header teil der E-Mail ist; wenn nicht, dann liegt der Fehler auf der Code-Seite. Ansonsten, sollte die Validierung vorhanden aber ungültig sein, liegt es meist am Key-Pair.

Lohnt sich DKIM?

Ganz klar: Ja.

DKIM ist relevant für das Spam-Scoring; und entsprechend sollten automatisierte E-Mails - zB. von Plattformen und Webseiten - ein entsprechend hohes Scoring haben, sodass eben solche Mails nicht im Spam-Filter landen und die Kommunikation mit dem Anwender erschweren.

Dank dem MimeKit und dem MailKit ist das - zumindest aus .NET sicht für SMTP - jedoch kein Problem mehr.


Let's Work Together

Looking for an experienced Platform Architect or Engineer for your next project? Whether it's cloud migration, platform modernization or building new solutions from scratch - I'm here to help you succeed.

New Platforms
Modernization
Training & Consulting

Comments

Twitter Facebook LinkedIn WhatsApp