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

如何修改Bouncy Castle代码生成与OpenSSL一致的命名曲线CSR

Bouncy Castle生成与OpenSSL一致的EC CSR修改方案

以下是针对差异点的具体修改项,覆盖公钥编码、签名算法、字段顺序、扩展编码等核心对齐点:


1. 公钥使用命名曲线编码(而非显式参数)

OpenSSL生成EC CSR时,公钥默认通过命名曲线OID标识参数,而Bouncy Castle默认可能输出显式曲线参数。需修改公钥生成逻辑,强制使用命名曲线格式:

// 替换原公钥获取代码,生成带命名曲线标识的公钥参数
var curveOid = curve.Oid;
var publicKey = new ECPublicKeyParameters(
    "ECDSA",
    keyPair.Public.Q,
    curveOid
);

2. 签名算法OID与OpenSSL对齐

OpenSSL的SHA256withECDSA对应标准OID 1.2.840.10045.4.3.2,需明确指定该OID创建签名工厂:

// 使用标准OID创建签名工厂,匹配OpenSSL签名算法标识
var signatureFactory = new Asn1SignatureFactory(
    "1.2.840.10045.4.3.2",
    keyPair.Private,
    secureRandom
);

3. 固定Subject DN字段顺序

Hashtable的键枚举是无序的,而OpenSSL的Subject DN字段顺序由命令行指定顺序决定,需手动指定字段顺序:

// 明确Subject DN字段顺序,匹配OpenSSL输出
var subjectAttrKeys = new ArrayList {
    X509Name.C,
    X509Name.O,
    X509Name.OU,
    X509Name.CN
};
var subjectName = new X509Name(subjectAttrKeys, subjectAttributes);

4. 固定Subject Alternative Name字段顺序

同理,Subject Alternative Name中的目录名字段顺序需手动指定,避免Hashtable的无序问题:

// 明确Subject Alternative Name字段顺序
var sanAttrKeys = new ArrayList {
    X509Name.Surname,
    X509Name.UID,
    X509Name.T,
    RegisteredAddress,
    X509Name.BusinessCategory
};
var subjectAltNames = new X509Name(sanAttrKeys, subjectAlternativeNameAttributes);

5. 调整Microsoft证书模板扩展编码

OpenSSL中该扩展通常直接编码模板名称的UTF-8字节,替换原DisplayText方式:

// 改为直接编码模板名称字节,匹配OpenSSL扩展格式
byte[] templateBytes = Encoding.UTF8.GetBytes("Test-Signing");
extensionsGenerator.AddExtension(MicrosoftObjectIdentifiers.MicrosoftCertTemplateV1, false, new DerOctetString(templateBytes));

完整修改后代码

var curve = ECNamedCurveTable.GetByName("secp256k1");
var domainParams = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());

var secureRandom = new SecureRandom();
var keyParams = new ECKeyGenerationParameters(domainParams, secureRandom);

var generator = new ECKeyPairGenerator("ECDSA");
generator.Init(keyParams);

var keyPair = generator.GenerateKeyPair();

// 带命名曲线标识的公钥参数
var curveOid = curve.Oid;
var publicKey = new ECPublicKeyParameters(
    "ECDSA",
    keyPair.Public.Q,
    curveOid
);

IDictionary subjectAttributes = new Hashtable();
subjectAttributes.Add(X509Name.CN, "Test1");
subjectAttributes.Add(X509Name.O, "Test2");
subjectAttributes.Add(X509Name.OU, "Test3");
subjectAttributes.Add(X509Name.C, "SA");
            
DerObjectIdentifier RegisteredAddress = new DerObjectIdentifier("2.5.4.26");

IDictionary subjectAlternativeNameAttributes = new Hashtable();
subjectAlternativeNameAttributes.Add(X509Name.Surname, "TestSN");
subjectAlternativeNameAttributes.Add(X509Name.UID, "010101010101010");
subjectAlternativeNameAttributes.Add(X509Name.T, "1100");
subjectAlternativeNameAttributes.Add(RegisteredAddress, "Test Address");
subjectAlternativeNameAttributes.Add(X509Name.BusinessCategory, "IT");

// 固定Subject DN字段顺序
var subjectAttrKeys = new ArrayList {
    X509Name.C,
    X509Name.O,
    X509Name.OU,
    X509Name.CN
};
var subjectName = new X509Name(subjectAttrKeys, subjectAttributes);

// 固定Subject Alternative Name字段顺序
var sanAttrKeys = new ArrayList {
    X509Name.Surname,
    X509Name.UID,
    X509Name.T,
    RegisteredAddress,
    X509Name.BusinessCategory
};
var subjectAltNames = new X509Name(sanAttrKeys, subjectAlternativeNameAttributes);
var generalNames = new GeneralNames(new[] { new GeneralName(subjectAltNames) });

var extensionsGenerator = new X509ExtensionsGenerator();
// 调整Microsoft证书模板扩展编码
byte[] templateBytes = Encoding.UTF8.GetBytes("Test-Signing");
extensionsGenerator.AddExtension(MicrosoftObjectIdentifiers.MicrosoftCertTemplateV1, false, new DerOctetString(templateBytes));
extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, generalNames);

var extensions = extensionsGenerator.Generate();

// 使用标准OID创建签名工厂
var signatureFactory = new Asn1SignatureFactory(
    "1.2.840.10045.4.3.2",
    keyPair.Private,
    secureRandom
);

var attributes = new AttributeX509(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(extensions));

var requestAttributeSet = new DerSet(attributes);

var certificateRequest = new Pkcs10CertificationRequest(signatureFactory, subjectName, publicKey, requestAttributeSet);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:32:41