Перейти к содержимому
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

Связанные ошибки

Открыть всю базу ошибок подписей