本文へスキップ
ecdsa.com
.NET SslStream / HttpClient.NET

エラーメッセージ

The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot

別の表記

  • System.Security.Authentication.AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot

コロンの後のフラグは X509ChainStatusFlags の値で、組み合わさることがあります(例:「UntrustedRoot, RevocationStatusUnknown」)。自己署名のサーバー証明書でも UntrustedRoot が報告されます。.NET は、Linux では OpenSSL とディストリビューションの CA ストアを、Windows と macOS ではシステムの証明書ストアを使います。

.NET SslStream / HttpClient — AuthenticationException (X509ChainStatusFlags.UntrustedRoot)

このエラーの意味

.NET はサーバーの証明書チェーンをルートまで構築しましたが、そのルートはプラットフォームのストアで信頼されていません(または、チェーンが信頼されていない自己署名証明書で終わっています)。証明書自体には問題がない場合もあり、単にマシンがその背後にある認証局を信頼していないだけです。HttpClient は、これを「The SSL connection could not be established」の内部例外として報告します。

発生する理由

修正方法

  1. 1.

    Linux:ルートをシステムのストアにインストールする

    Linux 上の .NET は OpenSSL のストアを読み込むため、update-ca-certificates(またはディストリビューションの同等のコマンド)を実行すれば十分です。コンテナーでは 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 と macOS:システムのストアでルートを信頼する

    Windows では LocalMachine\Root に、macOS ではシステムキーチェーンにルートをインポートしてください。.NET はこれらのストアを使います。

    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.

    特定のクライアントだけでプライベートルートを信頼する

    SocketsHttpHandler.SslOptions.CertificateChainPolicy で CustomRootTrust を使うと、完全な検証を維持したまま、信頼の起点を独自のルートにできます。カスタムポリシーではオンラインでの失効確認が既定で有効になるため、CA が公開している内容に合わせて RevocationMode を設定してください(ecdsa.com のテストでは、CRL/OCSP のないプライベート証明書は、NoCheck を設定するまで RevocationStatusUnknown で失敗しました)。

    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.

    開発環境:ASP.NET Core の開発用証明書を信頼する

    dotnet dev-certs https --trust は、Windows と macOS で localhost の開発用証明書をインストールして信頼済みにします(Linux では、信頼させる方法がディストリビューションによって異なります)。

    bash
    # ASP.NET Core development certificate on localhost
    dotnet dev-certs https --trust

関連するエラー

署名エラーデータベースをすべて見る