Message d’erreur
The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Également affiché sous la forme
- System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Les indicateurs qui suivent les deux-points viennent de X509ChainStatusFlags et peuvent se combiner (par exemple « UntrustedRoot, RevocationStatusUnknown »). Les certificats serveur auto-signés signalent eux aussi UntrustedRoot. Sous Linux, .NET utilise OpenSSL et le magasin d’AC de la distribution ; sous Windows et macOS, les magasins de certificats du système.
.NET SslStream / HttpClient — AuthenticationException (X509ChainStatusFlags.UntrustedRoot)
Ce que cela signifie
.NET a construit la chaîne de certificats du serveur jusqu’à une racine, et cette racine n’est pas approuvée par le magasin de la plateforme (ou la chaîne se termine par un certificat auto-signé non approuvé). Le certificat lui-même est peut-être correct ; c’est simplement que la machine ne fait pas confiance à l’autorité qui se trouve derrière. HttpClient signale cette erreur comme exception interne de « The SSL connection could not be established ».
Pourquoi cela se produit
Une AC d’entreprise ou privée
fréquenteLes API internes, SQL Server avec un certificat émis par l’AC du domaine ou des services de laboratoire utilisent des racines que la machine (souvent un conteneur Linux) n’a pas.
Un proxy d’inspection TLS
fréquenteLes connexions re-signées remontent jusqu’à la racine du proxy. Les machines Windows la reçoivent généralement par une stratégie de groupe, ce qui n’est pas le cas des conteneurs Linux ni de WSL.
Un certificat serveur auto-signé
fréquenteLes certificats auto-signés (y compris ceux des serveurs de développement) terminent eux-mêmes leur propre chaîne et sont signalés comme UntrustedRoot.
L’image du conteneur ne contient pas la racine
occasionnelleUne racine installée sur l’hôte ou dans Windows n’est pas présente dans le conteneur Linux où s’exécute l’application .NET.
Comment corriger l’erreur
- 1.
Linux : installer la racine dans le magasin du système
Sous Linux, .NET lit le magasin d’OpenSSL : update-ca-certificates (ou l’équivalent de la distribution) suffit donc ; dans les conteneurs, faites-le dans le Dockerfile.
bash # Linux (incl. containers): .NET uses the OpenSSL system store sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates - 2.
Windows et macOS : approuver la racine dans le magasin du système
Importez la racine dans LocalMachine\Root sous Windows ou dans le trousseau Système sous macOS ; .NET utilise ces magasins.
text # Windows (elevated PowerShell): trust the root machine-wide Import-Certificate -FilePath .\corp-root-ca.cer -CertStoreLocation Cert:\LocalMachine\Root # macOS sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain corp-root-ca.pem - 3.
Approuver une racine privée pour un seul client
SocketsHttpHandler.SslOptions.CertificateChainPolicy avec CustomRootTrust conserve la validation complète, mais l’ancre dans votre racine. Une politique personnalisée active par défaut la vérification de révocation en ligne : réglez donc RevocationMode selon ce que publie votre AC (dans notre test, des certificats privés sans CRL ni OCSP échouaient avec RevocationStatusUnknown tant que NoCheck n’était pas défini).
csharp // Trust one private root for this client only; chain, dates and name are still verified. var root = X509CertificateLoader.LoadCertificateFromFile("corp-root-ca.pem"); var handler = new SocketsHttpHandler(); handler.SslOptions.CertificateChainPolicy = new X509ChainPolicy { TrustMode = X509ChainTrustMode.CustomRootTrust, // a custom policy defaults to online revocation checks; use NoCheck only if the CA publishes no CRL/OCSP RevocationMode = X509RevocationMode.NoCheck, }; handler.SslOptions.CertificateChainPolicy.CustomTrustStore.Add(root); using var client = new HttpClient(handler); - 4.
Développement : approuver le certificat de développement ASP.NET Core
dotnet dev-certs https --trust installe et approuve le certificat de développement localhost sous Windows et macOS (sous Linux, la façon de l’approuver dépend de la distribution).
bash # ASP.NET Core development certificate on localhost dotnet dev-certs https --trust
Erreurs associées
The SSL connection could not be established, see inner exception..NET HttpClientThe remote certificate is invalid because of errors in the certificate chain: P….NET SslStream / HttpClientThe remote certificate was rejected by the provided RemoteCertificateValidation….NET SslStream / HttpClientcurl: (60) SSL certificate problem: self-signed certificate in certificate chaincurl (OpenSSL backend)