Skip to main content
 首页 » 编程设计

C#:以安全的方式正确发送电子邮件

2024年01月12日33dflying

尝试使用 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("me@example.com", "Me"); 
            var to = new MailAddress("you@example.com", "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 = "me@example.com", 
                    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 发送电子邮件?

我自己做验证的原因是默认验证失败,因为它是一个 self 颁发的证书,我使用的邮件域与使用的证书中的不同。我使用的是 mail.mydomain.com,而证书中的域类似于 mywebhost.com。所以我所做的是使用它的邮件客户端从 Opera 获取证书文件并存储它,以便我可以将它与尝试发送电子邮件时获得的文件进行比较。这是进行此验证的安全且好的方法吗?我也知道实际证书的哈希值,并试图用它来与我发送电子邮件时收到的证书进行比较。这也有效并且更容易做到,尽管在代码行中它几乎相同。只是与字符串而不是文件进行比较。这些方法中的任何一种比另一种更好吗?

请您参考如下方法:

您没有检查证书有效期,也没有检查它是否已被服务器吊销。一般来说,正确的证书验证是非常重要的事情。

有效期检查很简单 - 只需检查证书的 ValidFrom 和 ValidTo 属性。验证时刻必须介于两者之间。至于吊销检查——如果您有一个自签名证书,服务器维护人员很可能会费心管理 CRL 或安装 OCSP 服务器进行在线验证。因此,您可以在您的特定情况下跳过此步骤。

最后,如果服务器将证书更改为另一个合法证书怎么办?您将需要更改您的代码(或带有证书的文件),不是吗?