2010-06-09 51 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

相关问题