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

.NET 8 ASP.NET API证书认证失败:签名无法验证求助

问题描述

我正在开发基于.NET 8的ASP.NET应用,其API接口采用证书认证。测试环境中使用自签名证书或PKI证书时认证正常,但生产客户端调用作为域测试环境的Kestrel开发服务器时,触发OnAuthenticationFailed,错误日志如下:

Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationHandler[2]
      Certificate validation failed, subject was CN=PC1.contoso.com. NotSignatureValid The signature of the certificate cannot be verified.
Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationHandler: Warning: Certificate validation failed, subject was CN=PC1.contoso.com. NotSignatureValid The signature of the certificate cannot be verified.

我的证书认证配置代码如下:

.AddCertificate(CertificateAuthenticationDefaults.AuthenticationScheme, options =>
{
    options.RevocationMode = X509RevocationMode.NoCheck;
    options.AllowedCertificateTypes = CertificateTypes.All;
    var cer = builder.Configuration.GetSection("Certificate").GetSection("Root").GetValue<string>("TrustStore");
    var cer_int = "Resource\Sub CA.cer";
    var cer_root = "Resource\Root CA.cer";
    //options.CustomTrustStore.AddRange(new X509Certificate2Collection {new X509Certificate2(Path.Combine(cer_root))});
    options.CustomTrustStore.Add(new X509Certificate2(Path.Combine(cer_root)));
    options.CustomTrustStore.Add(new X509Certificate2(Path.Combine(cer_int)));
    options.ChainTrustValidationMode = X509ChainTrustMode.CustomRootTrust;

Kestrel配置如下:

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.ConfigureHttpsDefaults(options =>
    {
        options.AllowAnyClientCertificate();
        options.CheckCertificateRevocation = false;
        options.ClientCertificateMode = ClientCertificateMode.DelayCertificate;
        
    });
});

我已尝试将生产环境的根证书和中级证书添加到CustomTrustStore,甚至导入本地证书存储。该应用最终将部署为Azure Web App,因此用Kestrel测试(暂不知Azure调试方法),且客户端在Kestrel和Azure中的反应类似。请问为何证书会被拒绝?


排查与解决方案

针对NotSignatureValid错误,可从以下几个方向逐一排查:

1. 修复证书路径解析问题

代码中证书路径使用了反斜杠\,在C#字符串中反斜杠是转义字符,若未使用@前缀或转义为\\,会导致路径解析错误,证书无法正确加载到CustomTrustStore中。

解决方法:
将路径改为带@的逐字字符串,或使用正斜杠:

var cer_int = @"Resource\Sub CA.cer";
var cer_root = @"Resource\Root CA.cer";
// 或
var cer_int = "Resource/Sub CA.cer";
var cer_root = "Resource/Root CA.cer";

同时可添加日志验证证书是否成功加载:

var rootCert = new X509Certificate2(Path.Combine(cer_root));
var intCert = new X509Certificate2(Path.Combine(cer_int));
// 添加日志确认证书信息
logger.LogInformation("Root CA loaded: {Subject}", rootCert.Subject);
logger.LogInformation("Sub CA loaded: {Subject}", intCert.Subject);
options.CustomTrustStore.Add(rootCert);
options.CustomTrustStore.Add(intCert);

2. 验证证书链的签名关系

即使加载了根和中级证书,需确保客户端证书的签名链完整:

  • 客户端证书必须由配置的中级CA签发
  • 中级CA证书必须由配置的根CA签发
  • 检查证书的颁发者与主题是否匹配:中级CA的主题应等于客户端证书的颁发者,根CA的主题应等于中级CA的颁发者

验证方法:
双击客户端证书,查看「证书路径」标签,确认链中所有证书都已正确添加到CustomTrustStore,无缺失环节。

3. 完善CustomRootTrust的链验证逻辑

.NET 8中使用CustomRootTrust时,链验证仅信任CustomTrustStore中的根证书,不会自动包含系统信任存储。需确保:

  • 中级CA证书已显式添加到CustomTrustStore
  • 中级CA证书的签名由根CA签发,且根CA在CustomTrustStore中

4. 调整证书加载的存储标志

加载.cer证书时,可指定X509KeyStorageFlags避免权限问题导致验证失败:

var rootCert = new X509Certificate2(Path.Combine(cer_root), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
var intCert = new X509Certificate2(Path.Combine(cer_int), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);

5. 手动构建证书链调试

在认证中间件中添加自定义验证逻辑,输出链验证的具体失败信息:

options.Events = new CertificateAuthenticationEvents
{
    OnCertificateValidated = context =>
    {
        var chain = new X509Chain();
        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
        chain.ChainPolicy.CustomTrustStore.AddRange(options.CustomTrustStore);
        chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
        
        bool isValid = chain.Build(context.ClientCertificate);
        if (!isValid)
        {
            foreach (var status in chain.ChainStatus)
            {
                context.Logger.LogError("Chain validation failed: {Status} - {Info}", status.Status, status.StatusInformation);
            }
            context.Fail("Certificate chain validation failed");
        }
        return Task.CompletedTask;
    }
};

6. Azure Web App环境的特殊配置

若部署到Azure Web App,需额外注意:

  • 将根证书和中级证书上传到Azure「TLS/SSL设置」的「证书」模块,或确保证书文件包含在应用程序包中
  • 在Azure Web App配置中启用「客户端证书模式」为「需要」或「可选」
  • 用Path.GetFullPath(cer_root)输出实际路径到日志,验证路径是否正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:15:16