Aller au contenu
ecdsa.com
.NET SslStream / HttpClient.NET

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

Comment corriger l’erreur

  1. 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. 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. 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. 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

Parcourir toute la base de données des erreurs de signature