Golang生成CSR时ExtendedKeyUsage无法正常写入求助
问题:ExtendedKeyUsage字段无法在Golang生成的CSR中正常生效
我在编写一个基于用户输入生成CSR的小型Golang工具时遇到异常:ExtendedKeyUsage字段无法正常生效。使用Go版本为go1.19.3 darwin/amd64。
相关ASN.1编码及CSR模板代码如下:
var oidEmailAddress = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1} var OidExtensionKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 15} var OidExtensionExtendedKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37} asn1KeyUsageDigSig, err := asn1.Marshal(asn1.BitString{ Bytes: []byte{byte(x509.KeyUsageDigitalSignature)}, BitLength: 8, }) asn1KeyUsageDatEnc, err := asn1.Marshal(asn1.BitString{ Bytes: []byte{byte(x509.KeyUsageDataEncipherment)}, BitLength: 8, }) asn1KeyUsageCAuth, err := asn1.Marshal(asn1.BitString{ Bytes: []byte{byte(x509.ExtKeyUsageClientAuth)}, BitLength: 8, }) if err != nil { Error.Fatalf("Can't serialize Extended Key Usage %s", err) }
template := x509.CertificateRequest{ RawSubject: asn1Subj, EmailAddresses: []string{emailAddress}, SignatureAlgorithm: _sigAlg, ExtraExtensions: []pkix.Extension{ { Id: OidExtensionExtendedKeyUsage, Value: asn1KeyUsageCAuth, }, { Id: OidExtensionKeyUsage, Critical: true, Value: asn1KeyUsageDatEnc, }, { Id: OidExtensionKeyUsage, Critical: true, Value: asn1KeyUsageDigSig, }, }, } csrBytes, _ := x509.CreateCertificateRequest(rand.Reader, &template, privateKey)
通过openssl req -in MY_OUTPUT.csr -text -noout查看生成的CSR时,ExtendedKeyUsage字段为空,显示如下:
****** ASN1 OID: prime256v1 NIST CURVE: P-256 Attributes: Requested Extensions: X509v3 Subject Alternative Name: email:someone@somewhere.com X509v3 Extended Key Usage: .... X509v3 Key Usage: critical Key Agreement X509v3 Key Usage: critical Encipher Only Signature Algorithm: ecdsa-with-SHA256 ******
预期该字段应显示为X509v3 Extended Key Usage: ClientAuthentication,但实际为空,尝试更换OID对应的字节也无效。
解决方案
问题出在ExtendedKeyUsage的ASN.1编码格式错误,同时KeyUsage的使用方式也存在问题:
核心错误点:
- ExtendedKeyUsage编码错误:你误用
asn1.BitString序列化x509.ExtKeyUsageClientAuth,但ExtendedKeyUsage的ASN.1定义是KeyPurposeId的序列(SEQUENCE),即多个OID组成的列表,而非单个OID转成的比特串。 - KeyUsage重复添加:KeyUsage是一个包含多个权限的单比特串,不应拆分多次添加同名扩展。
修正后的代码:
- 正确序列化ExtendedKeyUsage:
// ExtendedKeyUsage需要序列化OID的序列 extendedKeyUsages := []asn1.ObjectIdentifier{x509.ExtKeyUsageClientAuth} asn1ExtendedKeyUsage, err := asn1.Marshal(extendedKeyUsages) if err != nil { log.Fatalf("Can't serialize Extended Key Usage %s", err) }
- 合并KeyUsage权限并序列化:
// 合并多个KeyUsage到单个比特串 keyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment asn1KeyUsage, err := asn1.Marshal(asn1.BitString{ Bytes: []byte{byte(keyUsage)}, BitLength: 8, }) if err != nil { log.Fatalf("Can't serialize Key Usage %s", err) }
- 更新CSR模板:
template := x509.CertificateRequest{ RawSubject: asn1Subj, EmailAddresses: []string{emailAddress}, SignatureAlgorithm: _sigAlg, ExtraExtensions: []pkix.Extension{ { Id: OidExtensionExtendedKeyUsage, Value: asn1ExtendedKeyUsage, }, { Id: OidExtensionKeyUsage, Critical: true, Value: asn1KeyUsage, }, }, } csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &template, privateKey) if err != nil { log.Fatalf("Failed to create CSR: %s", err) }
验证结果:
重新生成CSR后,执行openssl req -in MY_OUTPUT.csr -text -noout,ExtendedKeyUsage字段将正常显示:
X509v3 Extended Key Usage: Client Authentication
内容的提问来源于stack exchange,提问作者suxarik
相关产品推荐
相关产品推荐

