跳到主要内容
ecdsa.com
.NET SslStream / HttpClient.NET

错误信息

The remote certificate was rejected by the provided RemoteCertificateValidationCallback.

该文本在 .NET Core 和 .NET 5~10 中保持不变;HttpClient 会把它包装在外层异常“The SSL connection could not be established, see inner exception.”中。传给回调的 SslPolicyErrors 值可以告诉你 .NET 自身是否也发现了问题。

.NET SslStream / HttpClient — a custom validation callback returned false

含义

应用安装了自己的证书验证回调(ServerCertificateCustomValidationCallback 或 RemoteCertificateValidationCallback),而该回调返回了 false。.NET 的内置检查可能已经通过;是你的代码决定拒绝该证书。这在服务器证书续期或轮换后、使用了证书固定或公钥固定的场景中很常见。

原因

修复方法

  1. 1.

    记录回调看到的内容

    在回调中记录 SslPolicyErrors、主体、SHA-256 指纹和过期时间,然后更新固定值列表或修复证书。

    csharp
    ServerCertificateCustomValidationCallback = (request, cert, chain, errors) =>
    {
        var thumbprint = cert!.GetCertHashString(HashAlgorithmName.SHA256);
        logger.LogWarning("TLS {Host}: errors={Errors} subject={Subject} sha256={Thumb} notAfter={NotAfter:u}",
            request.RequestUri?.Host, errors, cert.Subject, thumbprint, cert.NotAfter);
        return errors == SslPolicyErrors.None && pinnedThumbprints.Contains(thumbprint);
    },
  2. 2.

    固定公钥,并保留一个备用固定值

    只要续期时沿用同一密钥,SPKI 固定值就始终有效;务必至少再固定一个备用密钥,避免密钥轮换时把客户端拒之门外。

    bash
    # Pin the public key (SPKI) rather than the certificate: it survives renewals with the same key
    openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null \
      | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64

相关错误

浏览完整的签名错误库