You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何ASP.NET Core Kestrel加载自签名根证书后仍需存入受信任根证书存储?

问题

我有一个基于ASP.NET Core 6与Kestrel Web Server的应用,要求客户端与服务器之间采用mTLS通信。我通过PowerShell的New-SelfSignedCertificate cmdlet生成了自签名根证书及客户端子证书,并通过以下代码将根证书显式加载到Kestrel:

var rootCertFile ="xxx.pfx";
var rootCertPw = "abc";
X509Certificate2 rootCert = new X509Certificate2( rootCertFile,  rootCertPw);

webBuilder.ConfigureKestrel(o =>
{
    o.ConfigureHttpsDefaults(o =>
    {
        o.ServerCertificate = rootCert;
        o.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
    });
});

webBuilder.UseKestrel(o =>
{
    o.Listen(IPAddress.Parse(myHttpsEndPointIpAddr), myHttpsEndPointPort,
        listenOptions =>
        {
            listenOptions.UseHttps();
        });
    o.Listen(IPAddress.Parse(myHttpEndPointIpAddr), myHttpEndPointPort);
});

当客户端(如curl或Postman)使用由该根证书签名的子证书调用HTTPS端点时,若根证书未存入本地机器的Trusted Root Certification Authorities Certificate Store,客户端会收到错误并被拒绝调用,错误信息如下:

* TLSv1.2 (IN), TLS header, Unknown (21):
* TLSv1.2 (IN), TLS alert, unknown CA (560):
* OpenSSL SSL_read: error:0A000418:SSL routines::tlsv1 alert unknown ca, errno 0
* Failed receiving HTTP2 data
* OpenSSL SSL_write: SSL_ERROR_ZERO_RETURN, errno 0
* Failed sending HTTP2 data

一旦将根证书添加到本地机器的Trusted Root Certification Authorities Certificate Store,API调用即可成功。请问为何Kestrel已直接加载自签名根证书,仍需将其安装到受信任根证书存储中?

回答

核心原因是你搞反了验证方向:

  • 你在Kestrel里设置的ServerCertificate是服务器用来向客户端证明自己身份的证书,而mTLS里客户端验证服务器身份的逻辑是客户端本地完成的,和Kestrel有没有加载根证书完全没关系。
  • 客户端发起HTTPS请求时,会先校验服务器证书的合法性:你的服务器证书由自签名根CA签发,但客户端默认只信任系统预装的公共根CA,根本不认可你这个自定义的根CA,所以会抛出"unknown CA"错误。
  • 把根证书加到客户端机器的受信任根存储,本质是告诉客户端:这个根CA是可信的,由它签发的服务器证书可以放心信任。

另外补充一点:你当前的Kestrel配置其实没完成mTLS的完整验证——你只要求客户端提供证书,但没配置Kestrel去验证客户端证书是否由可信根CA签发。正确做法是在ConfigureHttpsDefaults里添加客户端证书验证逻辑,指定信任的根CA,示例代码如下:

o.ClientCertificateValidation = (cert, chain, errors) =>
{
    // 验证客户端证书是否由指定的根CA签发
    return chain.ChainElements.Cast<X509ChainElement>()
                .Any(element => element.Certificate.Thumbprint == rootCert.Thumbprint)
           && errors == SslPolicyErrors.None;
};

这样Kestrel才会真正校验客户端证书的合法性,而不是只要求客户端提供证书就行。

内容的提问来源于stack exchange,提问作者RickyTad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:55:25