如何用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
相关产品推荐
相关产品推荐

