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

本地开发CA证书生成及C# X509Certificate2验证失败求助

本地CA证书生成与C#验证失败问题排查

问题概述

在Ubuntu系统通过OpenSSL脚本生成本地开发用CA证书后,使用C#的X509Certificate2类加载证书对象成功,但调用Verify()方法时验证失败。通过X509Chain调试发现错误状态为PartialChain,提示信息为unable to get local issuer certificate。

OpenSSL证书生成脚本

#!/usr/bin/env bash

name=server

rm -rf tmp certs

mkdir tmp
mkdir certs

echo "Generate certificate authority"
openssl genrsa -out "tmp/${name}CA.key" 2048
openssl req -x509 -config certificate-authority-options.conf -new -nodes -key "tmp/${name}CA.key" -sha256 -days 825 -out "certs/${name}CA.pem"

echo "Generate CA-signed Certificate"
openssl genrsa -out "certs/${name}.key" 2048
openssl req -new -config certificate-authority-options.conf -key "certs/${name}.key" -out "tmp/${name}.csr"

echo "Generate SSL Certificate"
openssl x509 -req -in "tmp/${name}.csr" -CA "certs/${name}CA.pem" -CAkey "tmp/${name}CA.key" -CAcreateserial -out "certs/${name}.crt" -days 825 -sha256 -extfile options.conf

# Cleanup stray file
rm certs/*.srl

配置文件

options.conf

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:TRUE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth, codeSigning, emailProtection
subjectAltName = @alt_names

[alt_names]
# Local hosts
DNS.1 = localhost
DNS.2 = 127.0.0.1
DNS.3 = ::1

DNS.4 = local.dev

certificate-authority-options.conf

[req]
prompt = no
distinguished_name = req_distinguished_name

[req_distinguished_name]
C = US
ST = Fake State
L = Fake Locality
O = Fake Company
OU = Org Unit Name
emailAddress = info@example.com
CN = local.dev

C#测试代码

using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace Test;

public static class Program
{
    public static async Task Main(string[] args)
    {
        var certificate = new X509Certificate2("my-certificate-path");
        
        var chain = new X509Chain();

        try
        {
            var chainBuilt = chain.Build(certificate);
           
            if (chainBuilt == false)
                foreach (var chainStatus in chain.ChainStatus)
                {
                    var d = chainStatus.Status;
                    var b = chainStatus.StatusInformation;
                }
                  
        }
        catch (Exception ex)
        {
            // ignored
        }

        if (!certificate.Verify())
        {
            throw new Exception("Could not verify the current certificate");
        }
    }
}

错误信息

  • X509Chain.ChainStatus状态:PartialChain
  • 状态说明:unable to get local issuer certificate

解决方案建议

1. 修正服务器证书的CA约束

服务器证书属于终端实体证书,不应具备CA签发权限,修改options.conf中的basicConstraints配置:

basicConstraints=CA:FALSE

2. 确保根CA证书被信任

系统层面(Ubuntu)

将生成的根CA证书serverCA.pem添加到系统信任存储:

sudo cp certs/serverCA.pem /usr/local/share/ca-certificates/serverCA.crt
sudo update-ca-certificates

代码层面(C#)

若不想修改系统信任,可在代码中手动将根CA证书加入证书链的信任列表:

var certificate = new X509Certificate2("path/to/server.crt");
var caCert = new X509Certificate2("path/to/serverCA.pem");

var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.Add(caCert);
// 适配本地开发场景,允许未知证书颁发机构
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;

var chainBuilt = chain.Build(certificate);

3. 生成包含完整链的PFX证书(可选)

将服务器证书、私钥和根CA证书合并为PFX格式,方便C#一次性加载完整证书链:

openssl pkcs12 -export -out certs/server.pfx -inkey certs/server.key -in certs/server.crt -certfile certs/serverCA.pem

在C#中加载PFX文件:

var certificate = new X509Certificate2("path/to/server.pfx", "your-set-password");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:46:18