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

如何通过.cnf文件创建公钥、私钥及CSR?

基于.cnf文件生成RSA密钥对和CSR的C#实现

你的核心问题有两个:现有代码完全未读取.cnf中的distinguished_name字段,且密钥对生成未达预期。以下是直接可用的解决方案:

一、解析.cnf文件提取DN字段

首先需要读取.cnf文件,解析出[dn]段的所有身份字段:

private static Dictionary<string, string> ParseCnfFile(string cnfPath)
{
    var dnFields = new Dictionary<string, string>();
    var lines = File.ReadAllLines(cnfPath);
    bool inDnSection = false;

    foreach (var line in lines)
    {
        var trimmedLine = line.Trim();
        if (trimmedLine.StartsWith("[dn]"))
        {
            inDnSection = true;
            continue;
        }
        if (!inDnSection || string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#"))
            continue;

        var parts = trimmedLine.Split(new[] { '=' }, 2);
        if (parts.Length != 2) continue;

        var key = parts[0].Trim();
        var value = parts[1].Trim();
        // 统一处理带数字前缀的OU字段
        if (key.StartsWith("1.") || key.StartsWith("2.") || key.StartsWith("3."))
        {
            key = "OU";
        }
        // 多个OU用逗号拼接
        if (dnFields.ContainsKey(key))
        {
            dnFields[key] += $", {value}";
        }
        else
        {
            dnFields[key] = value;
        }
    }
    return dnFields;
}

二、生成密钥对和CSR

原生.NET类库没有直接生成CSR的API,推荐使用BouncyCastle.NetCore NuGet包简化操作,它能完整利用.cnf的所有字段。

1. 安装依赖

在NuGet包管理器中执行:

Install-Package BouncyCastle.NetCore

2. 完整实现代码

using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using System.IO;
using System.Text;

private static void GenerateKeyPairAndCsrFromCnf(string cnfPath)
{
    // 解析.cnf中的DN字段
    var dnFields = ParseCnfFile(cnfPath);

    // 生成2048位RSA密钥对
    var keyGen = new RsaKeyPairGenerator();
    keyGen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
    var keyPair = keyGen.GenerateKeyPair();

    // 构造X509身份名称
    var x509Name = new X509Name();
    foreach (var field in dnFields)
    {
        switch (field.Key)
        {
            case "CN":
                x509Name.AddX509NameEntry(X509Name.CN, field.Value);
                break;
            case "serialNumber":
                x509Name.AddX509NameEntry(X509Name.SerialNumber, field.Value);
                break;
            case "O":
                x509Name.AddX509NameEntry(X509Name.O, field.Value);
                break;
            case "OU":
                // 拆分多个OU并逐个添加
                var ous = field.Value.Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var ou in ous)
                {
                    x509Name.AddX509NameEntry(X509Name.OU, ou);
                }
                break;
            case "C":
                x509Name.AddX509NameEntry(X509Name.C, field.Value);
                break;
        }
    }

    // 生成CSR(证书签名请求)
    var csrGenerator = new Pkcs10CertificationRequestGenerator();
    csrGenerator.SetPublicKey(keyPair.Public);
    csrGenerator.SetSignatureAlgorithm("SHA256WithRSAEncryption");
    csrGenerator.SetSubject(x509Name);
    var csr = csrGenerator.Generate(keyPair.Private);

    // 导出私钥(PEM格式)
    string privateKeyPem = ConvertToPem(keyPair.Private, "RSA PRIVATE KEY");
    // 导出公钥(PEM格式)
    string publicKeyPem = ConvertToPem(keyPair.Public, "PUBLIC KEY");
    // 导出CSR(PEM格式)
    string csrPem = ConvertToPem(csr, "CERTIFICATE REQUEST");

    // 保存到文件
    File.WriteAllText("private_key.pem", privateKeyPem, Encoding.UTF8);
    File.WriteAllText("public_key.pem", publicKeyPem, Encoding.UTF8);
    File.WriteAllText("cert_request.csr", csrPem, Encoding.UTF8);
}

// 辅助方法:将对象转换为PEM格式字符串
private static string ConvertToPem(object obj, string header)
{
    var writer = new StringWriter();
    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(writer);
    pemWriter.WriteObject(obj);
    pemWriter.Writer.Flush();
    return writer.ToString();
}

三、原代码问题说明

  1. 未读取.cnf字段:原代码完全硬编码参数,未解析.cnf中的DN配置,无法复用文件中的身份信息。
  2. 密钥导出风险:RemoveXmlTags方法可能破坏XML格式的密钥结构,导致密钥无法正常使用,推荐使用标准PEM格式。
  3. 缺少CSR生成逻辑:原代码仅生成密钥对,未实现CSR的创建,而这是证书申请的必要步骤。

使用方式

直接调用方法传入.cnf文件路径即可:

GenerateKeyPairAndCsrFromCnf(@"C:\your\path\config.cnf");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:45:18