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

如何在C#中通过CSR文件生成符合要求的RSA公钥?

问题解决:C#生成的RSA公钥与OpenSSL输出不兼容

核心问题分析

  • 私钥格式差异:OpenSSL生成的是PKCS#8无加密私钥(头部-----BEGIN PRIVATE KEY-----),而你的BouncyCastle代码默认输出PKCS#1格式RSA私钥(头部-----BEGIN RSA PRIVATE KEY-----),格式不匹配会导致API验证失败。
  • 公钥格式差异:OpenSSL从CSR导出的公钥是SPKI(SubjectPublicKeyInfo)格式(头部-----BEGIN PUBLIC KEY-----),你的代码直接写入RsaPublicKey会生成PKCS#1格式公钥,这是API不认的关键原因。
  • 编码细节:OpenSSL用-utf8参数处理特殊字符(比如[Stamp]),需要确保C#代码的DN字段也用UTF-8编码。

修正后的BouncyCastle代码

1. 私钥输出改为PKCS#8格式

通过PrivateKeyInfoFactory转换格式后写入:

using (var fw = File.CreateText("fa.key"))
{
    var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
    var writer = new PemWriter(fw);
    writer.WriteObject(privateKeyInfo);
}

2. 公钥输出改为SPKI格式

用SubjectPublicKeyInfoFactory转换后写入,匹配OpenSSL的公钥格式:

var publicKey = csr.GetPublicKey();
var publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);

using (var fw = File.CreateText("publickey.pem"))
{
    var writer = new PemWriter(fw);
    writer.WriteObject(publicKeyInfo);
}

3. 对齐UTF-8编码与签名算法

显式指定UTF-8处理DN特殊字符,确保和OpenSSL的-utf8参数一致:

// 用UTF-8编码创建Subject,避免特殊字符乱码
var subject = new X509Name(X509Name.DefaultStyle, Encoding.UTF8.GetBytes(subjectName));

完整修正代码

var subjectName = "CN=MyCompany [Stamp],O=Non-Governmental,serialNumber=12345678910,C=US";

// 显式用UTF-8编码处理Subject中的特殊字符
var subject = new X509Name(X509Name.DefaultStyle, Encoding.UTF8.GetBytes(subjectName));

// 生成2048位RSA密钥对
var randomGenerator = new CryptoApiRandomGenerator();
var random = new SecureRandom(randomGenerator);
const int strength = 2048;
var keyGenerationParameters = new KeyGenerationParameters(random, strength);

var keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(keyGenerationParameters);
var subjectKeyPair = keyPairGenerator.GenerateKeyPair();

// 写入PKCS#8格式私钥(和OpenSSL输出一致)
using (var fw = File.CreateText("fa.key"))
{
    var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
    var writer = new PemWriter(fw);
    writer.WriteObject(privateKeyInfo);
}

// 生成PKCS#10 CSR,签名算法保持SHA1WITHRSA
var csr = new Pkcs10CertificationRequest("SHA1WITHRSA", subject, subjectKeyPair.Public, null, subjectKeyPair.Private);

// 导出CSR到文件
var csrPem = new StringBuilder();
var csrPemWriter = new PemWriter(new StringWriter(csrPem));
csrPemWriter.WriteObject(csr);
csrPemWriter.Writer.Flush();

using (StreamWriter f = new StreamWriter(@"fa.csr"))
{
    f.Write(csrPem.ToString());
}

// 生成SPKI格式公钥(匹配OpenSSL导出的公钥)
var publicKey = csr.GetPublicKey();
var publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);

using (var fw = File.CreateText("publickey.pem"))
{
    var writer = new PemWriter(fw);
    writer.WriteObject(publicKeyInfo);
}

替代库推荐

如果嫌BouncyCastle API繁琐,可考虑:

  • OpenSSL.NET:直接调用OpenSSL原生接口,行为和手动执行命令完全一致,无需担心格式匹配问题。
  • Certes:API简洁,专注证书相关操作,支持生成标准格式的CSR、密钥对和公钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:53:33