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

Bouncy Castle中Subject Alternative Names输出不正确问题

问题根因
  • 未遵循SAN扩展的ASN.1编码规范:直接将X509Name对象裸写入扩展值,没有封装为GeneralNames→GeneralName的标准结构,也没有为DirName类型打对应的显式标签(标签值为4),导致证书解析工具无法识别结构,只能输出原始二进制乱码。
  • 字段OID映射错误:你将需要的registeredAddress字段错写为X509Name.PostalAddress(邮政地址,OID 2.5.4.16),和要求的registeredAddress(OID 2.5.4.26)不是同一个字段;title字段直接用短名T存在映射风险,建议直接使用明确的X509Name.Title常量。
  • 原有代码存在语法瑕疵:KeyUsage定义处的注释未闭合,会导致编译错误。
修正方案
  1. 修正字段映射,替换错误的OID常量
  2. 使用BouncyCastle内置的GeneralName、GeneralNames类封装DirName结构,指定名称类型为DirectoryName
  3. 将封装完成的SAN结构编码后传入扩展值,不要直接传入X509Name对象
修正后的核心代码
// 修正字段OID映射
var alt_names = new Dictionary<DerObjectIdentifier, string> {
    {X509Name.SerialNumber, "334623324234325"},
    {X509Name.UID, "310122393500003"},
    {X509Name.Title, "0000"},
    {X509Name.RegisteredAddress, "Sample E"},
    {X509Name.BusinessCategory, "Sample Business"}
};

// 构造DirName实体
var dirName = new X509Name(alt_names.Keys.Reverse().ToList(), alt_names);
// 按SAN标准结构封装:指定为DirName类型,包装进GeneralNames序列
var sanExtensionValue = new GeneralNames(new GeneralName(GeneralName.DirectoryName, dirName));

var extensions = new Dictionary<DerObjectIdentifier, X509Extension>()
{
    {X509Extensions.BasicConstraints, new X509Extension(true,
    new DerOctetString(new BasicConstraints(false)))},
    {X509Extensions.KeyUsage, new X509Extension(true,
    new DerOctetString(new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment)))}
};

// 证书模板扩展保持原有逻辑
string certificateTemplateName = "1.3.6.1.4.1.311.20.2";
DerObjectIdentifier certificateTemplateExtensionOid = new DerObjectIdentifier("1.3.6.1.4.1.311.20.2");
DerSequence certificateTemplateExtension = new DerSequence(
        new DerObjectIdentifier(certificateTemplateName), new DerPrintableString("ZATCA-Code-Signing"));
extensions.Add(certificateTemplateExtensionOid, new X509Extension(false, new DerOctetString(certificateTemplateExtension)));

// 传入封装完成的SAN结构编码
extensions.Add(X509Extensions.SubjectAlternativeName, new X509Extension(false,
        new DerOctetString(sanExtensionValue.GetDerEncoded())));

说明:代码中保留了Reverse()反转键顺序的逻辑,保证输出的字段顺序和你期望的SN→UID→title→registeredAddress→businessCategory一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 00:27:24