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

如何在Go中生成指定Subject顺序的CSR证书签名请求

如何在Go中自定义CSR Subject字段顺序

Go标准库的crypto/x509/pkix包中,pkix.Name的默认处理逻辑会按固定顺序(Country → Locality → Organization → OrganizationalUnit → ... → CommonName)生成Subject的RDN序列,无法直接通过修改pkix.Name的字段来调整输出顺序。要实现自定义顺序,需要手动构造pkix.RDNSequence并直接指定Subject的原始ASN.1编码。

实现步骤

  1. 明确字段对应OID:每个Subject字段都有对应的ASN.1 OID,常用字段的OID如下:

    • 国家(C): 2.5.4.6
    • 组织(O): 2.5.4.10
    • 组织单元(OU): 2.5.4.11
    • 地区(L): 2.5.4.7
    • 通用名称(CN): 2.5.4.3
  2. 按目标顺序构造RDN序列:

    • 每个RelativeDistinguishedNameSET对应Subject中的一个逗号分隔项
    • 多个同类型字段(如多个OU)需要放在同一个RelativeDistinguishedNameSET中,这样会生成OU=OU1 + OU=OU2的格式
  3. 编码RDN序列并赋值给Subject.Raw:

    • 将构造好的pkix.RDNSequence编码为ASN.1 DER格式
    • 把编码后的数据赋值给pkix.Name.Raw,这样生成CSR时会直接使用该原始数据,而非默认排序后的内容

完整代码示例

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"os"
)

func main() {
	// 生成RSA私钥
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		panic(err)
	}

	// 按目标顺序构造RDN序列
	rdnSequence := pkix.RDNSequence{
		// C = IN
		{{Type: []int{2, 5, 4, 6}, Value: "IN"}},
		// O = Example Org
		{{Type: []int{2, 5, 4, 10}, Value: "Example Org"}},
		// OU = OU1 + OU = OU2
		{
			{Type: []int{2, 5, 4, 11}, Value: "OU1"},
			{Type: []int{2, 5, 4, 11}, Value: "OU2"},
		},
		// L = loc
		{{Type: []int{2, 5, 4, 7}, Value: "loc"}},
		// CN = example.com
		{{Type: []int{2, 5, 4, 3}, Value: "example.com"}},
	}

	// 将RDN序列编码为ASN.1 DER
	rawSubject, err := asn1.Marshal(rdnSequence)
	if err != nil {
		panic(err)
	}

	// 构造CSR模板
	csrTemplate := &x509.CertificateRequest{
		Subject: pkix.Name{
			Raw: rawSubject, // 使用自定义的原始Subject数据
		},
		SignatureAlgorithm: x509.SHA256WithRSA,
	}

	// 生成CSR的DER编码
	csrDER, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, privateKey)
	if err != nil {
		panic(err)
	}

	// 将DER编码转为PEM格式并写入文件
	csrPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrDER})
	if err := os.WriteFile("custom_order.csr", csrPEM, 0644); err != nil {
		panic(err)
	}
}

验证结果

运行代码后,使用OpenSSL命令查看CSR的Subject:

openssl req -in custom_order.csr -text -noout

输出的Subject会符合预期顺序:

Subject: C = IN, O = Example Org, OU = OU1 + OU = OU2, L = loc, CN = example.com

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:53:15