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

如何用C#结合BouncyCastle基于配置文件生成CSR

在C#中使用BouncyCastle基于配置文件生成CSR

首先安装BouncyCastle NuGet包:

dotnet add package BouncyCastle

以下是完整的实现代码,包含配置文件解析、私钥加载、CSR生成及输出逻辑:

using System;
using System.IO;
using System.Collections.Generic;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

public class CsrGenerator
{
    public static void GenerateCsrFromConfig(string configFilePath, string privateKeyPath, string outputCsrPath)
    {
        // 1. 解析配置文件,提取主题和扩展信息
        var configData = ParseCsrConfig(configFilePath);
        
        // 2. 加载PEM格式私钥
        AsymmetricKeyParameter privateKey;
        using (var reader = new StreamReader(privateKeyPath))
        {
            var pemReader = new PemReader(reader);
            privateKey = (AsymmetricKeyParameter)pemReader.ReadObject();
        }
        
        // 3. 构建证书请求主题
        var subject = new X509Name(configData.SubjectEntries);
        
        // 4. 准备主题备用名称(SAN)扩展
        var extensions = new List<X509Extension>();
        if (configData.AltNames?.Count > 0)
        {
            var sanBuilder = new GeneralNames();
            foreach (var dnsName in configData.AltNames)
            {
                sanBuilder.AddName(new GeneralName(GeneralName.DnsName, dnsName));
            }
            extensions.Add(new X509Extension(X509Extensions.SubjectAlternativeName, false, sanBuilder.ToAsn1Object()));
        }
        
        // 5. 初始化CSR生成器
        var csrGenerator = new Pkcs10CertificationRequestGenerator();
        csrGenerator.SetPublicKey(privateKey);
        csrGenerator.SetSignatureAlgorithm("SHA256withRSA"); // 可根据需求调整算法
        csrGenerator.SetSubject(subject);
        
        // 添加扩展项
        if (extensions.Count > 0)
        {
            var extGenerator = new X509ExtensionsGenerator();
            foreach (var ext in extensions)
            {
                extGenerator.AddExtension(ext.Oid, ext.Critical, ext.GetValue());
            }
            csrGenerator.AddAttribute(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, extGenerator.Generate());
        }
        
        // 生成签名后的CSR
        var secureRandom = new SecureRandom(new CryptoApiRandomGenerator());
        var csr = csrGenerator.Generate(privateKey, secureRandom);
        
        // 6. 输出CSR到指定文件
        using (var writer = new StreamWriter(outputCsrPath))
        {
            var pemWriter = new PemWriter(writer);
            pemWriter.WriteObject(csr);
            pemWriter.Writer.Flush();
        }
    }

    // 解析OpenSSL风格的CSR配置文件
    private static CsrConfigData ParseCsrConfig(string configFilePath)
    {
        var configData = new CsrConfigData
        {
            SubjectEntries = new List<KeyValuePair<string, string>>(),
            AltNames = new List<string>()
        };
        
        var lines = File.ReadAllLines(configFilePath);
        var currentSection = string.Empty;
        
        foreach (var line in lines)
        {
            var trimmedLine = line.Trim();
            // 切换配置段
            if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
            {
                currentSection = trimmedLine.Trim('[', ']');
                continue;
            }
            // 跳过空行和注释
            if (string.IsNullOrEmpty(currentSection) || trimmedLine.StartsWith("#"))
                continue;
            
            var parts = trimmedLine.Split('=', 2);
            if (parts.Length != 2)
                continue;
            
            var key = parts[0].Trim();
            var value = parts[1].Trim().Trim('"');
            
            // 提取主题字段和SAN条目
            switch (currentSection)
            {
                case "req_distinguished_name":
                    configData.SubjectEntries.Add(new KeyValuePair<string, string>(key, value));
                    break;
                case "alt_names":
                    if (key.StartsWith("DNS."))
                    {
                        configData.AltNames.Add(value);
                    }
                    break;
            }
        }
        
        return configData;
    }

    private class CsrConfigData
    {
        public List<KeyValuePair<string, string>> SubjectEntries { get; set; }
        public List<string> AltNames { get; set; }
    }
}

// 使用示例
class Program
{
    static void Main(string[] args)
    {
        var configPath = @"path/to/your/csr.conf";
        var privateKeyPath = @"path/to/your/private.key";
        var outputCsrPath = @"path/to/output/csr.csr";
        
        CsrGenerator.GenerateCsrFromConfig(configPath, privateKeyPath, outputCsrPath);
    }
}

补充说明

  • 配置解析逻辑支持标准OpenSSL配置格式,可识别[req_distinguished_name]段的主题字段(如CN、O、OU等)和[alt_names]段的DNS条目。
  • 默认使用SHA256withRSA签名算法,如需更换可修改SetSignatureAlgorithm的参数(如SHA384withRSA)。
  • 私钥支持PEM格式的RSA密钥,若使用EC密钥,需调整私钥加载和签名算法对应逻辑。
  • 如需处理更复杂的配置规则(如默认值、变量替换),可扩展ParseCsrConfig方法。

内容的提问来源于stack exchange,提问作者Abdussalam Al-shaebi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:25:22