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

使用.NET生成可被OpenSSL验证的CA签名证书方法

问题描述

参考相关技术回答提供的代码逻辑,将生成的parentCert根证书与cert终端证书保存为.crt格式文件后,尝试通过如下OpenSSL命令完成证书链验证:

openssl verify -CAfile parentCert.crt cert.crt

命令执行失败,返回如下错误信息:

Error loading file parentCert.crt
98580000:error:05800088:x509 certificate routines:X509_load_cert_crl_file_ex:no certificate or crl found:crypto\x509\by_file.c:251:

核心诉求为:如何在.NET环境中正确创建CA根证书(ca.crt)以及由该CA签名的终端证书(cert.crt),确保生成的证书可被OpenSSL正常完成验证。

测试用C#代码

本次测试使用的完整C#代码如下:

using (RSA parent = RSA.Create(4096))
using (RSA rsa = RSA.Create(2048))
{
    CertificateRequest parentReq = new CertificateRequest(
        "CN=Experimental Issuing Authority",
        parent,
        HashAlgorithmName.SHA256,
        RSASignaturePadding.Pkcs1);

    parentReq.CertificateExtensions.Add(
        new X509BasicConstraintsExtension(true, false, 0, true));

    parentReq.CertificateExtensions.Add(
        new X509SubjectKeyIdentifierExtension(parentReq.PublicKey, false));

    using (X509Certificate2 parentCert = parentReq.CreateSelfSigned(
        DateTimeOffset.UtcNow.AddDays(-45),
        DateTimeOffset.UtcNow.AddDays(365)))
    {
        CertificateRequest req = new CertificateRequest(
            "CN=Valid-Looking Timestamp Authority",
            rsa,
            HashAlgorithmName.SHA256,
            RSASignaturePadding.Pkcs1);

        req.CertificateExtensions.Add(
            new X509BasicConstraintsExtension(false, false, 0, false));

        req.CertificateExtensions.Add(
            new X509KeyUsageExtension(
                X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
                false));

        req.CertificateExtensions.Add(
            new X509EnhancedKeyUsageExtension(
                new OidCollection
                {
                new Oid("1.3.6.1.5.5.7.3.8")
                },
                true));

        req.CertificateExtensions.Add(
            new X509SubjectKeyIdentifierExtension(req.PublicKey, false));

        using (X509Certificate2 cert = req.Create(
            parentCert,
            DateTimeOffset.UtcNow.AddDays(-1),
            DateTimeOffset.UtcNow.AddDays(90),
            new byte[] { 1, 2, 3, 4 }))
        {
            // 可对生成的证书执行后续操作,例如导出为PFX格式、添加到X509Store证书存储等

            string path = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\"));
            File.WriteAllBytes(Path.Combine(path, "parentCert.crt"), parentCert.Export(X509ContentType.Cert));
            File.WriteAllBytes(Path.Combine(path, "cert.crt"), cert.Export(X509ContentType.Cert));
        }
    }
}
问题原因与修复方案

根因分析

现有证书生成逻辑本身的扩展配置没有问题:根证书正确开启了CA基础约束,终端证书关闭了CA标记,密钥用法、增强型密钥用法配置均符合规范。
报错的核心原因是证书文件编码格式不匹配:

  • 调用Export(X509ContentType.Cert)导出的是DER二进制编码格式的证书内容
  • OpenSSL的verify命令默认读取PEM格式(Base64编码,带-----BEGIN CERTIFICATE-----头尾标记)的证书文件,直接读取DER二进制文件就会抛出找不到证书/CRL的错误。

修复方式

推荐优先使用第一种修复方式,PEM是.crt格式的通用默认编码,跨平台、跨工具兼容性最好。

  • 方式1:修改证书导出逻辑,保存为PEM格式文件
    如果使用.NET 5及以上版本,可以直接用内置PemEncoding类生成PEM内容,替换原有文件写入逻辑即可:

    // 替换原有的File.WriteAllBytes导出代码
    // 导出根证书为PEM格式
    string parentCertPem = PemEncoding.Write("CERTIFICATE", parentCert.RawData);
    File.WriteAllText(Path.Combine(path, "parentCert.crt"), parentCertPem);
    // 导出终端证书为PEM格式
    string certPem = PemEncoding.Write("CERTIFICATE", cert.RawData);
    File.WriteAllText(Path.Combine(path, "cert.crt"), certPem);
    

    如果使用.NET 5以下版本,可以手动拼接PEM格式内容:

    string ConvertCertToPem(X509Certificate2 cert)
    {
        string base64Content = Convert.ToBase64String(cert.RawData, Base64FormattingOptions.InsertLineBreaks);
        return $"-----BEGIN CERTIFICATE-----\n{base64Content}\n-----END CERTIFICATE-----";
    }
    

    修改后直接执行原OpenSSL验证命令,返回cert.crt: OK即为验证通过。

  • 方式2:保留现有DER格式导出,修改OpenSSL命令指定文件编码
    如果不需要调整文件导出逻辑,可以在OpenSSL命令中添加参数分别指定CA根证书、待验证终端证书的编码格式为DER:

    openssl verify -CAfile parentCert.crt -CAform DER cert.crt -inform DER
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:45:43