Message d’erreur
The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
Texte stable dans .NET Core et .NET 5 à 10 ; HttpClient l’enveloppe dans « The SSL connection could not be established, see inner exception. » La valeur SslPolicyErrors transmise au callback vous indique si .NET a lui aussi trouvé un problème.
.NET SslStream / HttpClient — a custom validation callback returned false
Ce que cela signifie
L’application a installé son propre callback de validation de certificat (ServerCertificateCustomValidationCallback ou RemoteCertificateValidationCallback), et ce callback a renvoyé false. Les vérifications intégrées de .NET ont peut-être réussi ; c’est votre code qui a décidé de rejeter le certificat. Cas typique : l’épinglage de certificat ou de clé, après le renouvellement ou la rotation du certificat du serveur.
Pourquoi cela se produit
Le certificat épinglé a été remplacé
fréquenteL’épinglage de l’empreinte d’un certificat ne résiste à aucun renouvellement (désormais à quelques mois d’intervalle avec les AC publiques) ; le nouveau certificat a une nouvelle empreinte.
La logique propre au callback rejette des certificats valides
fréquenteDes vérifications portant sur un nom d’émetteur exact, un sujet ou une liste d’empreintes qui ne correspondent plus, ou des conditions qui ignorent les erreurs transmises dans l’argument errors.
Le callback rejette à juste titre un vrai problème
occasionnelleUn callback qui renvoie errors == SslPolicyErrors.None rejette les certificats non approuvés, expirés ou dont le nom ne correspond pas ; la cause est alors le certificat lui-même.
Comment corriger l’erreur
- 1.
Journaliser ce que voit le callback
Enregistrez SslPolicyErrors, le sujet, l’empreinte SHA-256 et la date d’expiration dans le callback, puis mettez à jour la liste des empreintes épinglées ou corrigez le certificat.
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.
Épingler la clé publique et garder une empreinte de secours
Les empreintes SPKI épinglées restent valides lors des renouvellements qui réutilisent la clé ; épinglez toujours au moins une clé de secours pour qu’une rotation ne bloque pas les clients.
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