我正在尝试使用加密库在 go 中创建证书签名请求。问题是它生成的 CSR 中的 OU 用
+
分隔,即
Subject: O = Example Org, OU = OU1 + OU = OU2, CN = example.com
如何生成 OU 之间用
,
分隔的 CSR,如
Subject: O = Example Org, OU = OU1, OU = OU2, CN = example.com
生成由
+
分隔的 OU 似乎是 crypto
lib 的默认行为。这可以使用加密库来完成吗?如果没有,那么是否有其他库可以生成 CSR,其中 OU 用 ,
分隔
我尝试使用下面的代码生成 CSR
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"os"
)
func main() {
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
csrTemplate := x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "example.com",
Organization: []string{"Example Org"},
OrganizationalUnit: []string{"OU1", "OU2"},
},
EmailAddresses: []string{"[email protected]"},
}
csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, privKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
csrPem := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: csrBytes,
})
fmt.Println(string(csrPem))
}
“+”和“,”都不是证书的一部分。这正是提供人类可读的证书字符串表示形式时所使用的内容。
详细说明:您的代码只是打印出 PEM 格式的 CSR 文件,而不是人类可读的证书表示形式。使用 asn1parse 查看此 CSR 会给出:
$ openssl asn1parse -in csr.pem
...
37:d=4 hl=2 l= 10 cons: SEQUENCE
39:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
44:d=5 hl=2 l= 3 prim: PRINTABLESTRING :OU1
49:d=4 hl=2 l= 10 cons: SEQUENCE
51:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
56:d=5 hl=2 l= 3 prim: PRINTABLESTRING :OU2
61:d=3 hl=2 l= 20 cons: SET
因此,这些是单独的对象,而不是中间有“+”的组合字符串。当使用 req 显示证书时,会出现此“+”:
$ openssl req -in csr.pem -text
Certificate Request:
Data:
Version: 1 (0x0)
Subject: O = Example Org, OU = OU1 + OU = OU2, CN = example.com
这里使用哪个分隔符实际上可以进行配置。请参阅 openssl-namedisplay-options 并查找
sep_comma_plus_space
,这是默认分隔符。引用文档:
第一个单词用于相对可分辨名称 (RDN) 之间,第二个单词用于多个属性值断言 (AVA) 之间。多个 AVA 非常罕见,不鼓励使用。
所以你已经明白了:在不同的 RDN(即 O、OU、CN、...)之间使用逗号,而在同一 RDN 内的多个 AVA 之间使用加号(如多个 OU)。另外,无论如何,不鼓励使用多个 AVA。