2017-01-31 35 views
2

我看到一個奇怪的問題,而DKIM使用Mailkit &對Mimekit進行簽名,Gmail報告錯誤「dkim = neutral(body hash not校驗)」。DKIM簽名失敗,身體哈希沒有驗證Mimekit 1.10.1.0,Mailkit 1.10.2.0

我在這裏做錯了什麼?請在下面找到我的代碼並截取Gmail image 1headers附帶的實際收到的郵件。

 string ReturnName = "DMC12"; 
     string FromDomain = "backtothefuture.net"; 
     string FromEmail = "[email protected]" + FromDomain; 
     string FromName = "Marty McFly"; 
     string SenderName = "Marty McFly"; 
     string ToEmail = "[email protected]"; 
     string MailServer = "DMC12.large.timemachine.com"; 
     string TextBody = @"If you put your mind to it, you can accomplish anything. One other thing. If you guys ever have kids, and one of them, when he's eight years old, accidentally sets fire to the living room rug... go easy on him!"; 
     string HtmlBody = string.Format(@"<b>如果你把你的頭腦,它可以完成任何事情。 另一件事。 如果你們有孩子,其中一個,當他八歲時,不小心把火燒在客廳地毯上...去容易對他!</b>"); 
     string Subject = "Message from Marty (1960)!"; 
     string ToName = "George McFly"; 
     string DKIMdomain = FromDomain; 
     string DKIMSigner = "btfreturns.com";   
     string ReturnEmail = "[email protected]" + MailServer; 
     string SenderEmail = "[email protected]" + MailServer; 
     string privatekey = System.IO.File.ReadAllText("dkim.private.key"); 
     var client = new SmtpClient(new ProtocolLogger("smtp.txt")); // logging SMTP connections 

      try 
      { 
       client.Connect(MailServer, 25); 
      } 
      catch (SmtpCommandException ex) 
      { 
       Console.WriteLine("Error trying to connect: {0}", ex.Message); 
       Console.WriteLine("\tStatusCode: {0}", ex.StatusCode); 
       return; 
      } 
      catch (SmtpProtocolException ex) 
      { 
       Console.WriteLine("Protocol error while trying to connect: {0}", ex.Message); 
       return; 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
       return; 
      } 

      client.LocalDomain = MailServer; 

      var message = new MimeMessage(); 
      MailboxAddress RecepientAddress = new MailboxAddress(ToName, ToEmail); 

      message.From.Add(new MailboxAddress(FromName, FromEmail)); // From Address 
      var builder = new BodyBuilder(); 

      builder.TextBody = TextBody; 
      builder.HtmlBody = HtmlBody; 

      List<MailboxAddress> To = new List<MailboxAddress>(); 
      To.Add(RecepientAddress); 

      message.Subject = Subject; 
      message.Body = builder.ToMessageBody(); 
      message.Sender = new MailboxAddress(SenderName, SenderEmail); // Sender Address 
      message.To.Add(RecepientAddress);  
      message.MessageId = Guid.NewGuid().ToString("N") + "@" + new System.Net.Mail.MailAddress(message.Sender.Address).Host; 


       using (Stream s = (new MemoryStream(Encoding.UTF8.GetBytes(privatekey ?? "")))) 
       { 
        var headersToSign = new[] { HeaderId.From, HeaderId.To, HeaderId.Subject, HeaderId.Date, HeaderId.MessageId }; 
        var signer = new DkimSigner(s, DKIMdomain, DKIMSigner); 
        signer.SignatureAlgorithm = DkimSignatureAlgorithm.RsaSha1; 
        message.Sign(signer, headersToSign, DkimCanonicalizationAlgorithm.Relaxed, DkimCanonicalizationAlgorithm.Relaxed); 
       } 


       client.Send(message, new MailboxAddress(ReturnName, ReturnEmail), To);    
       client.Disconnect(true); 
       client.Connect(MailServer, 25); 
       client.Dispose(); 
+0

我想我知道這裏的問題是什麼。我在HtmlBody中使用Utf-8字符的事實是導致DKIM簽名失敗,如果我將它替換爲Standard Ascii chacaters,它可以正常工作,並且可以通過飛行色測試。 – Krylor

回答

2

問題是,在DKIM簽名消息之前,您沒有調用message.Prepare()。這是一個非常重要的步驟,因爲它會將消息正文的所有MIME部分強制爲用於傳輸的適當編碼。

請注意,如果你不叫Prepare()與適當的編碼約束值,該SmtpClient.Send()方法最終會做的是後,你已經DKIM簽名的消息,從而使簽名無效。

我的建議是使用EncodingConstraint.SevenBit以獲得最大的互操作性。

但是,如果你是知己,你的SMTP服務器和您的郵件將通過支持傳輸8BITMIME擴展名的所有其他SMTP服務器,那麼你可以嘗試使用EncodingConstraint.EightBit代替。

+0

謝謝@jsteadfast,它確實解決了我們的問題! – Krylor

+0

@jstedfast這是一篇很重要的文章,當然應該包含在文檔中。謝謝你的偉大答案! –

+0

它在REAMDE :) – jstedfast