跳到主要内容
ecdsa.com
.NET SslStream / HttpClient.NET

错误信息

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

常与其他标志同时出现,例如“PartialChain, RevocationStatusUnknown”。HttpClient 会把它包装在外层异常“The SSL connection could not be established, see inner exception.”中。

.NET SslStream / HttpClient — X509ChainStatusFlags.PartialChain: the chain could not be built up to a root

含义

.NET 无法从服务器证书一路构建出通往任何根证书的证书链:缺少中间证书。即使根证书受信任(如复现示例中那样),叶子证书与根证书之间的缺口也会导致验证无法完成。如果证书的颁发机构信息访问(Authority Information Access)扩展中有 URL 且可以访问,.NET 能从那里下载缺失的中间证书,因此这个错误主要出现在私有 CA、网络受限的环境和容器中。

原因

修复方法

  1. 1.

    检查服务器发送的内容

    如果握手中只有一张证书,且它由中间证书签发,就证实了这个问题。

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
  2. 2.

    让服务器发送完整证书链

    在我们的测试中,只通过 ServerCertificate 提供完整证书链 PEM 时,Kestrel(.NET 10)只发送了叶子证书;按示例设置 ServerCertificateChain 后,它才发送中间证书。对于 IIS,把中间证书安装到服务器的“中间证书颁发机构”存储中,Windows 就会发送它。

    csharp
    // Kestrel sends intermediates only when they are given as ServerCertificateChain
    builder.WebHost.ConfigureKestrel(k => k.ConfigureHttpsDefaults(o =>
    {
        o.ServerCertificate = X509Certificate2.CreateFromPemFile("fullchain.pem", "server.key");
        var chain = new X509Certificate2Collection();
        chain.ImportFromPemFile("fullchain.pem");   // leaf + intermediates
        o.ServerCertificateChain = chain;
    }));
  3. 3.

    找出缺失的中间证书

    叶子证书的 AIA 扩展指向颁发者证书;把该证书添加到服务器配置中。

    bash
    # The leaf names where its issuer can be downloaded (Authority Information Access)
    openssl x509 -in server.pem -noout -ext authorityInfoAccess

相关错误

浏览完整的签名错误库