How to DKIM sign and send email in .NET Core using Office 365 Email Server?

47 Views Asked by At

At our company, we work with universities to help them find and reach out to their alumni. We have a .Net Core web application hosted in Azure that allows partner universities to send emails to their alumni. One important requirement for us is to be able to send emails as our partner's domain using our Office 365 email server. To implement this, we have collaborated with NC State University (NCSU), one of our partners.

Here's what we did:

  1. Created DKIM key pairs using online DKIM record generator https://easydmarc.com/tools/dkim-record-generator. The domain is: ncsu.edu; the selector is: edvision; the key length is: 2048.

  2. Requested NCSU to publish a DKIM record in their domain DNS using the generated DKIM public key. The DKIM record can be looked up here: https://mxtoolbox.com/SuperTool.aspx?action=dkim%3ancsu.edu%3aedvision&run=toolpage

  3. Saved the private key internally for signing the message.

  4. Created an API for sending the email with DKIM signature using MimeKit, and MailKit library for .NET. Here's the API code:

public async Task<IActionResult> SendDkimWithMimeKit()
{
            try
            {
                string toAddress = HttpContext.Request.Form["toAddress"];
                string subject = "Test DKIM Email Integration";
                var message = new MimeMessage();
                message.To.Add(new MailboxAddress("Test Mailbox", toAddress));
                message.From.Add(new MailboxAddress("Test NCSU Mailbox", "[email protected]"));
                message.Subject = subject;
                // Sign the message with DKIM signature
                string domain = "ncsu.edu"; // partner domain
                string selector = "edvision"; // selector
                var headers = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.To };
                var signer = new MimeKit.Cryptography.DkimSigner(Path.Combine(_env.WebRootPath, "static/dkimkey.txt"),
                    domain, selector, DkimSignatureAlgorithm.RsaSha1)
                {
                    HeaderCanonicalizationAlgorithm = MimeKit.Cryptography.DkimCanonicalizationAlgorithm.Relaxed,
                    BodyCanonicalizationAlgorithm = MimeKit.Cryptography.DkimCanonicalizationAlgorithm.Relaxed,
                    AgentOrUserIdentifier = "@ncsu.edu",
                    QueryMethod = "dns/txt",
                };
                var builder = new BodyBuilder();
                builder.TextBody = "Test DKIM";
                builder.HtmlBody = "<p>Test DKIM</p>";
                message.Body = builder.ToMessageBody();
                // Prepare the message and sign
                message.Prepare(EncodingConstraint.SevenBit);
                signer.Sign(message, headers);
                // Send the email
                using (var client = new MailKit.Net.Smtp.SmtpClient())
                {
                    await client.ConnectAsync("edvision-ai.mail.protection.outlook.com", 25);
                    await client.SendAsync(message);
                    client.Disconnect(true);
                }
                return Ok();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return Ok(ex.Message);
            }
}

The expected outcome:

When our partner uses our web app to send emails to any valid email addresses, the recipients should receive the email as they were originated from our partner's domain. For example, a NCSU user with [email protected] email logs in to our site at edvision.ai, composes, and send an email to [email protected] in the app, then the owner of [email protected] should receive the email from [email protected].

What happened:

Instead of being able to send the email, our partner was getting the following error:

"5.7.64 TenantAttribution; Relay Access Denied [ValidationStatus of '' is EmptyCertificate] [DS1PEPF00017095.namprd03.prod.outlook.com 2024-02-29T16:12:55.562Z 08DC376E7A2E7644]"

Interestingly, our partner was able to send email to usf.edu email addresses. We think the reason why our partner can send the DKIM email to USF email addresses was because USF uses the same email hosting service as us which is Office 365.

At this point, we are not sure if the problem is with the DKIM signing process or with any mis-configuration in Microsoft 365.

What we have tried so far:

  • We have verified that our private key matches the public key in the DKIM record.
  • We have tried different .NET libraries for adding DKIM signature to the email including both free and paid libraries.
  • We have added connectors in Exchange Admin Center to make sure email send from our ip addresses can go through.
  • We have tested our code by allowing another email server to send email using our domain (edvision.ai) by publishing a DKIM record in our domain DNS, and using private key to send DKIM email using the other server, and it works.
0

There are 0 best solutions below