【问题标题】:C#: Sending emails in a secure way correctlyC#:以安全的方式正确发送电子邮件
【发布时间】:2010-06-09 21:37:58
【问题描述】:

尝试使用 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 发送电子邮件?

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

【问题讨论】:

    标签: c# validation email ssl ssl-certificate


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢!有效期检查是个好点。应该补充一下。您将如何检查证书是否已被吊销?如果服务器更改了证书,在我的情况下,我需要更改文件证书,是的,但这不是所有电子邮件客户端的工作方式吗?一个弹出窗口告诉您证书有问题,并询问您是否要从现在开始接受该证书或类似的内容。
    • 我为我们的 SecureBlackbox 产品实现了证书验证器组件,并且我们在那里有 OCSP 客户端和 CRL 组件,所以并不难。顺便说一句,我们有 SMTP 客户端组件,可以方便地进行所有检查,但对于您的简单任务来说,这可能是一种矫枉过正。
    【解决方案2】:

    只是代码的一个附带问题 - 为什么将参数 object sX509Chain chainSslPolicyErrors sslPolicyErrors 传递到 OurCertificateValidation 方法中?他们没有被引用。

    【讨论】:

    • 因为它们是委托签名的一部分?
    猜你喜欢
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多