我有同样的问题。首先,我使用下面的代码来保存 SMTP 服务器使用的证书的副本(因为我无权访问服务器本身/即使您有权访问,这也显示了正在呈现的服务器,因此可能会标记它是否不同达到您的预期)。我通过 LinqPad5 作为 c# 程序运行它。
void Main()
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(OutputCertificateCallback);
using (System.Net.Mail.SmtpClient S = new System.Net.Mail.SmtpClient("smtprelay.subdomain.example.com"))
{
S.EnableSsl = true;
using (System.Net.Mail.MailMessage M = new System.Net.Mail.MailMessage("john.bevan@example.com", "john.bevan@example.com", "Test", "Test"))
{
try
{
S.Send(M);
Console.WriteLine("Sent");
}
catch (Exception e)
{
Console.WriteLine("Error {0}", e);
}
}
}
}
private bool OutputCertificateCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine(certificate);
System.IO.File.WriteAllBytes(@"C:\Temp\cert.cer", certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));
var c2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate);
return c2.Verify();
}
然后我可以通过查看保存的文件来检查证书:C:\Temp\cert.cer
检查到期日期以确保证书有效。
如果不是,那就是问题所在。获取新证书。
检查我的客户受信任的 CA 中的根证书:
- 启动、运行、MMC
- 文件 > 添加/删除管理单元 > 证书 > 添加 > 我的用户帐户 > 完成 > 确定
- 证书 - 当前用户 > 受信任的根证书颁发机构 > 证书
- 在此列表中搜索根 CA(即与您的证书同名的 CA)
如果不是,您可能需要安装根 CA、中间 CA 或证书本身(您可以使用刚刚使用上述脚本保存的文件来完成)。
检查端口是否在防火墙上打开。您可以通过以下 PowerShell 进行测试:
try {
$tcp = New-Object -TypeName 'system.net.sockets.tcpclient' -ArgumentList 'smtprelay.subdomain.example.com', 465
if ($tcp.Connected) {':)'} else {':('}
} catch {
':('
$_.Exception.Message
}
就我而言,以上所有都不足以发现问题。最终我意识到该服务使用了通配符证书(例如*.example.com),但邮件服务器位于子域(例如smtprelay.subdomain.example.com)上,因此不在此证书范围内。在子域上使用通配符(例如*.subdomain.example.com)会起作用;虽然我们只是要求为服务提供一个明确命名的证书(对于smtprelay.subdomain.example.com),包括服务的各个节点的 FQDN 作为主题备用名称,以防我们需要针对特定节点进行调试。