2010-06-09 60 views
2

實驗使用C#發送安全電子郵件,並想知道我是否正確理解了事情。我目前有以下程序:C#:以正確的方式發送電子郵件

using System; 
using System.Net.Mail; 
using System.Net; 
using System.Security.Authentication; 
using System.Security.Cryptography.X509Certificates; 
using System.IO; 
using System.Net.Security; 

namespace Geekality.SecureEmail 
{ 
    class Program 
    { 
     static bool OurCertificateValidation(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
     { 
      var actualCertificate = X509Certificate.CreateFromCertFile("example.com.cert"); 

      return certificate.Equals(actualCertificate); 
     } 

     static void Main(string[] args) 
     { 
      // Register our own certificate validation 
      ServicePointManager.ServerCertificateValidationCallback = OurCertificateValidation; 

      // Message 
      var from = new MailAddress("[email protected]", "Me"); 
      var to = new MailAddress("[email protected]", "Myself"); 

      var message = new MailMessage(from, to) 
      { 
       Subject = "Greetings!", 
       Body = "How are you doing today?", 
      }; 

      // Create client 
      var client = new SmtpClient("smtp.example.com") 
      { 
       EnableSsl = true, 
       Credentials = new NetworkCredential 
       { 
        UserName = "[email protected]", 
        Password = "password", 
       }, 
      }; 

      // Try to send 
      using (client) 
      { 
       try 
       { 
        client.Send(message); 
        Console.WriteLine("Message sent!"); 
       } 
       catch (AuthenticationException e) 
       { 
        Console.WriteLine("Authentication failed:"); 
        Console.WriteLine(e.Message); 
       } 
       catch (SmtpException e) 
       { 
        Console.WriteLine("SMTP error:"); 
        Console.WriteLine(e.Message); 
       } 
      } 

      Console.ReadKey(true); 
     } 
    } 
} 

儘管數據當然已更改爲示例值。無論如何,這似乎很好地從我所能看到的。對我所做的事情有任何評論?特別是關於我如何進行證書驗證的問題。這是做這件事的好方法嗎?或者我錯過了這麼糟糕的東西,我不如使用SSL發送電子郵件?

的理由讓我做驗證自己是默認的驗證失敗,因爲它是一個自頒發的證書和我使用的郵件域是不一樣的是所使用的證書中。我正在使用mail.mydomain.com,而證書中的域名是mywebhost.com。所以我所做的就是使用它的郵件客戶端從Opera獲取證書文件並存儲它,以便我可以將它與我在嘗試發送電子郵件時獲得的相比較。這是做這個驗證的安全和好方法嗎?我也知道實際證書的散列,並試圖用它來比較發送電子郵件時獲得的證書。這也起作用,並且更容易做到,儘管在代碼行中它幾乎是一樣的。只需比較字符串而不是文件。這些方法是否比其他方法更好?

回答

0

您沒有檢查證書的有效期,也沒有檢查它是否沒有被服務器吊銷。一般來說,適當的證書驗證是非常不平凡的事情。

有效期檢查很簡單 - 只需檢查證書的ValidFrom和ValidTo屬性即可。驗證時間必須在兩者之間。至於撤銷檢查, - 如果您有自簽名證書,服務器維護人員有一點可能會打擾管理CRL或安裝OCSP服務器進行聯機驗證。所以你可以跳過這個步驟在你的特定情況下

最後,如果服務器將證書更改爲另一合法證書,該怎麼辦?你需要改變你的代碼(或者帶有證書的文件),不是嗎?

+0

謝謝!有效期檢查是一個很好的觀點。應該補充一點。你將如何檢查證書是否被撤銷? 如果服務器更改證書我會在我的情況下需要更改文件證書是的,但不是所有電子郵件客戶端的工作方式?一個彈出窗口告訴你證書有問題,並詢問你是否想從現在開始接受該證書,或者類似的東西。 – Svish 2010-06-10 09:06:56

+0

我爲我們的SecureBlackbox產品實施了證書驗證器組件,並且我們在那裏有OCSP客戶端和CRL組件,所以它並不難。順便說一下,我們有SMTP客戶端組件,它可以方便地執行所有檢查,但對於簡單的任務來說,這可能是一種矯枉過正。 – 2010-06-11 06:30:09

0

只是您的代碼的一個側面問題 - 爲什麼您將參數object sX509Chain chainSslPolicyErrors sslPolicyErrors轉換爲您的OurCertificateValidation方法?他們沒有被引用。

+0

因爲他們是委託簽名的一部分? – Svish 2010-06-10 09:04:06

相關問題