让 SmtpClient 使用自签名 SSL 证书

Posted

技术标签:

【中文标题】让 SmtpClient 使用自签名 SSL 证书【英文标题】:Getting SmtpClient to work with a self signed SSL certificate 【发布时间】:2011-01-10 08:38:57 【问题描述】:

我正在尝试使用 System.Net.Mail.SmtpClient 类通过我公司的电子邮件服务器中继电子邮件。与邮件服务器的所有 SMTP 连接都必须是 SSL,并且它使用自签名证书。这对 Outlook 来说很好,您可以在警告对话框中单击“确定”,但有人知道让 SmtpClient 接受自签名证书的方法吗?

我计划在 Windows Azure 平台上使用此应用程序,因此我无法将自签名证书安装为受信任的根。

【问题讨论】:

【参考方案1】:

您可以查看ServerCertificateValidationCallback 属性:

ServicePointManager.ServerCertificateValidationCallback = 
    (sender, certificate, chain, sslPolicyErrors) => true;

它表示运行时在尝试验证 SSL 证书时调用的回调。通过返回true,您基本上说您不在乎证书是否有效->您总是接受它。当然,在生产环境中拥有自签名证书并不是一个好主意。

【讨论】:

我确实稍微研究了 ServicePoint 的角度,但我在 ServicePoint/Members 文档页面“为 HTTP 连接提供连接管理”上看到了这条评论,所以我觉得它不会用于SMTP。另外,当我尝试它并将日志消息放入回调中时,它从未被调用过。 您需要在尝试实例化SmtpClient 类时将其放在 之前,最好放在应用程序的某个全局初始化部分。【参考方案2】:

我的问题最终是 .Net SmtpClient 类显然不支持将端口 465 用于 SMTP SSL 连接。使用带有自签名 SSL 证书的端口 25 可以正常工作。

MSDN System.Net 论坛问题Can SmtpClient be configured to work with a self signed certificate?.

【讨论】:

【参考方案3】:

如果您想要更安全,您可能需要考虑执行以下操作:

theClient.EnableSsl = true;

ServicePointManager.ServerCertificateValidationCallback =
    (sender, certificate, chain, sslPolicyErrors) => 
        if (sender == theClient) 
            return true;
         else 
            // you should apply the code from this SO answer
            // https://***.com/a/25895486/795690
            // if you find that anything in your app uses this path
            throw new ApplicationException("Certificate validation is currently disabled, extra code neeeded here!");
        
    ;

在此代码中,我们仅为相关的特定 SMTP 客户端自动批准证书;我们有一个存根代码路径,如果您发现应用程序中的其他任何东西正在使用它,您应该升级到 explicitly reinstate default certificate validation。

在this SO answer 中,另一种仅在您真正想要的上下文中批准证书的有用方法。

【讨论】:

以上是关于让 SmtpClient 使用自签名 SSL 证书的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Python 请求信任自签名 SSL 证书?

如何让 python 信任我服务器的 TLS 自签名证书:ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败

如何添加自签名SSL证书 自签名SSL证书存风险

SSL证书无效是啥原因?

企业为啥不能使用自签名SSL证书?

Android使用SSL自签名证书