Mac本地.NET应用出现RemoteCertificateNameMismatch,Windows运行正常
我为开源项目开发了一对可通过SSL通信的.NET Core演示应用(服务器端为Executor,客户端为TradeClient),在Windows系统运行正常,但Mac系统上出现RemoteCertificateNameMismatch错误,异常信息如下:
Connecting to 127.0.0.1 on port 5001 Remote certificate was not recognized as a valid certificate: RemoteCertificateNameMismatch Unable to perform authentication against server: The remote certificate was rejected by the provided RemoteCertificateValidationCallback. Connection failed: System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
at [a few more lines of my app code...]
...
已确认两个平台使用完全相同的证书、CA证书、证书密码,客户端均指向127.0.0.1,请问忽略了Mac系统的哪些特殊行为?
排查方向及解决方法
证书SAN字段的本地地址兼容性
Windows对证书SAN(Subject Alternative Name)中的127.0.0.1和localhost兼容性更高,但Mac的SSL验证逻辑更严格:- 检查服务器证书的SAN字段,确保同时包含
127.0.0.1和localhost两个条目; - 若证书仅包含其中一个,客户端连接时改用对应地址(比如证书只有
localhost,客户端就连接localhost而非127.0.0.1)。
- 检查服务器证书的SAN字段,确保同时包含
Mac系统的证书信任策略
Mac钥匙串对自签名证书的信任规则与Windows不同:- 将CA证书导入Mac的系统钥匙串而非登录钥匙串;
- 导入后右键证书→显示简介→信任→将SSL选项设为“始终信任”。
.NET Core跨平台SSL实现差异
.NET Core在Mac上依赖OpenSSL,Windows用Schannel,两者对证书名称匹配的逻辑有区别:- 确认客户端代码中
AuthenticateAsClient方法的targetHost参数,与证书的CN或SAN条目完全一致; - 测试环境可临时在验证回调中兼容名称不匹配(生产环境禁用):
private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // 仅测试用,生产需严格验证 if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch && certificate.Subject.Contains("CN=localhost")) // 替换为你的证书CN { return true; } return sslPolicyErrors == SslPolicyErrors.None; }
- 确认客户端代码中
Mac的IPv6解析优先级
Mac默认优先使用IPv6,可能导致客户端实际连接::1而非127.0.0.1,但证书未包含IPv6本地地址:- 检查证书SAN是否包含
::1; - 修改客户端配置,强制使用IPv4连接。
- 检查证书SAN是否包含
内容的提问来源于stack exchange,提问作者Grant Birchmeier

