You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用SMTP SSL时X509Certificate报RemoteCertificateNameMismatch错误求助

证书验证问题排查与修复请求

我在Windows Server 2019上使用SMTP服务器发送邮件,最近给SmtpClient添加了client.EnableSsl = true;配置,同时在发送邮件的Windows服务里加入了以下代码:

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateCertificate);
...
public static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
    {
        return true;
    }
    if (certificate.GetCertHashString().ToLower() == CertificateThumbprint)
    {
        return true;
    }

    ...
}

目前遇到的问题是sslPolicyErrors值为RemoteCertificateNameMismatch,查看证书哈希时发现是我方的通配符证书(但并非每次都是,其他非我方证书可无错误通过)。该证书原本是Web服务器使用的,部署在IIS中,所有Web应用运行正常,我推测是IIS的关联导致它被SMTP服务调用。

目前我用校验证书指纹并返回true的临时方案解决,但肯定存在更规范的验证方式,想请教:

  • 我的证书到底出了什么问题?
  • 如何正确修复这个问题?

附证书信息:

Archived: false
Extensions: {System.Security.Cryptography.X509Certificates.X509ExtensionCollection}
FriendlyName: ""
Handle: 0x00000259a9ca7f70
HasPrivateKey: false
Issuer: "CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O=\"GoDaddy.com, Inc.\", L=Scottsdale, S=Arizona, C=US"
IssuerName: {System.Security.Cryptography.X509Certificates.X500DistinguishedName}
NotAfter: {5/2/2024 7:05:24 AM}
NotBefore: {4/1/2023 8:01:11 AM}
PrivateKey: null
PublicKey: {System.Security.Cryptography.X509Certificates.PublicKey}
RawData: {byte[1677]}
RawDataMemory: "System.ReadOnlyMemory<Byte>[1677]"
SerialNumber: "00AEE89C39F9916FF2"
SerialNumberBytes: "System.ReadOnlyMemory<Byte>[9]"
SignatureAlgorithm: {System.Security.Cryptography.Oid}
Subject: "CN=*.servername.com"
SubjectName: {System.Security.Cryptography.X509Certificates.X500DistinguishedName}
Thumbprint: "402010..........373DDA30F455"
Version: 3

问题分析与修复方案

问题根源

  1. 证书名称不匹配:RemoteCertificateNameMismatch的核心原因是,你连接SMTP服务器时使用的主机名(如IP、NetBIOS名称)和证书的Subject(CN=*.servername.com)不匹配。比如用IP而非xxx.servername.com格式的域名连接,通配符证书就无法完成匹配校验。
  2. SMTP关联了无密钥的证书副本:你提供的证书信息显示HasPrivateKey: false,但SMTP服务启用SSL/TLS时必须使用带私钥的证书才能完成密钥交换。当前SMTP调用的可能是IIS证书的无密钥副本,导致验证逻辑异常。
  3. SMTP服务证书绑定错误:Windows Server的SMTP服务会从服务器证书存储中自动挑选证书,IIS的通配符证书因是服务器级证书被选中,但该证书的域名与SMTP对外提供的主机名不匹配,触发验证错误。

正确修复步骤

步骤1:确认SMTP主机名与证书域名匹配

  • 检查代码中SmtpClient.Host的值,必须是xxx.servername.com格式的域名,禁止使用IP或NetBIOS名称,确保与证书的通配符*.servername.com匹配。

步骤2:为SMTP配置带私钥的正确证书

  1. 打开MMC证书管理单元:运行mmc → 添加证书管理单元 → 选择本地计算机 → 展开个人>证书,找到你的通配符证书,确认其带有私钥(右键属性可查看)。
  2. 如果证书无密钥,重新导入带私钥的PFX格式证书,导入时勾选“标记此密钥为可导出”。
  3. 配置SMTP服务绑定证书:打开IIS管理器,找到SMTP服务器→右键属性→切换到Access标签页→点击Certificate按钮→选择带私钥的通配符证书并确认。

步骤3:修正证书验证逻辑(替代临时指纹校验)

不要硬编码指纹,让逻辑正确验证域名匹配与信任链有效性:

public static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;
    }

    // 处理名称不匹配的情况,先验证域名是否实际匹配
    if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
    {
        string targetHost = string.Empty;
        if (sender is ServicePoint sp)
        {
            targetHost = sp.Address.Host;
        }

        var x509Cert = new X509Certificate2(certificate);
        // 验证证书域名与目标主机匹配
        if (x509Cert.VerifyHostname(targetHost))
        {
            // 验证证书信任链(生产环境可根据需求调整吊销检查策略)
            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            if (chain.Build(x509Cert))
            {
                return true;
            }
        }
    }

    // 其他错误场景直接返回false
    return false;
}

步骤4:验证SSL连接

  • 使用openssl s_client -connect smtp.servername.com:587(或对应SMTP SSL端口如465)测试连接,查看返回的证书信息是否正确,域名是否匹配。
  • 在代码中添加日志,记录连接的SMTP主机名与证书Subject,确认两者匹配。

内容的提问来源于stack exchange,提问作者Velocedge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:29:59