英文:
How to add keyUsage to certificate signing request in Golang
问题
我需要在一个 Golang 应用程序中创建一个指定 keyUsage certSign 的 PEM 编码的证书签名请求(CSR)。
在 Golang 中,函数 x509.CreateCertificateRequest 可以帮助实现这一目标,它接受一个 x509.CertificateRequest 输入参数。CertificateRequest 类型没有 KeyUsage 属性,所以我假设我必须使用它的 Extensions
属性来嵌入一个 KeyUsage 到 CSR 中。Extensions
属性的类型是 []pkix.Extension
,而 pkix Go 包并没有提供太多帮助来构建 KeyUsage 扩展。
KeyUsage 在 RFC5280 第 4.2.1.3 节 中被定义为一个带有 OBJECT IDENTIFIER id-ce 15 的 BIT STRING。下面的代码是否是创建 KeyUsage 的正确方式?是否有更简单的方法可以利用 pkix 或 x509 Go 包,避免自己进行位序列化?我的位序列化是否符合该 RFC,我该如何测试?
asn1KeyUsage, err := asn1.Marshal(asn1.BitString{
Bytes: []byte{byte(x509.KeyUsageCertSign)},
BitLength: 8,
})
if err != nil { ... }
csrTemplate := x509.CertificateRequest{
SignatureAlgorithm: ...,
PublicKeyAlgorithm: ...,
PublicKey: ...,
Subject: ...,
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier([]int{2, 5, 29, 15}),
Critical: true,
Value: asn1KeyUsage,
},
},
}
asn1, err = x509.CreateCertificateRequest(
rand.Reader,
csrTemplate,
privateKey,
)
// 将 asn1 转换为 PEM
英文:
I need to create a PEM-encoded Certificate Signing Request (CSR) that specifies keyUsage certSign in a Golang application.
In Golang, function x509.CreateCertificateRequest helps with this, and it takes an x509.CertificateRequest input parameter. Type CertificateRequest does not have a KeyUsage attribute, so I assume I must use its Extensions
attribute to embed a KeyUsage in that CSR. That Extensions
attribute is of type []pkix.Extension
and the pkix Go package does not really have much to help me build a KeyUsage extension.
KeyUsage is documented in RFC5280 section 4.2.1.3 as a BIT STRING with OBJECT IDENTIFIER id-ce 15. Would the following be the right way to create that KeyUsage? Is there no easier way that leverages the pkix or x509 Go packages and avoids doing my own bit serialization? Is my bit serialization even in compliance with that RFC, how can I test this?
asn1KeyUsage, err := asn1.Marshal(asn1.BitString{
Bytes: []byte{byte(x509.KeyUsageCertSign)},
BitLength: 8,
})
if err != nil { ... }
csrTemplate := x509.CertificateRequest{
SignatureAlgorithm: ...,
PublicKeyAlgorithm: ...,
PublicKey: ...,
Subject: ...,
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier([]int{2, 5, 29, 15}),
Critical: true,
Value: asn1KeyUsage,
},
},
}
asn1, err = x509.CreateCertificateRequest(
rand.Reader,
csrTemplate,
privateKey,
)
// Convert asn1 to PEM below
答案1
得分: 1
我也没有找到一种简洁的方法来向我的证书签名请求(CSR)中添加KeyUsage
。我查看了Golang的代码,并找到了这个。
最终,我提取了以下代码片段:
func marshalKeyUsage(ku x509.KeyUsage) (pkix.Extension, error) {
ext := pkix.Extension{Id: asn1.ObjectIdentifier{2, 5, 29, 15}, Critical: true}
var a [2]byte
a[0] = reverseBitsInAByte(byte(ku))
a[1] = reverseBitsInAByte(byte(ku >> 8))
l := 1
if a[1] != 0 {
l = 2
}
bitString := a[:l]
var err error
ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})
if err != nil {
return ext, err
}
return ext, nil
}
func reverseBitsInAByte(in byte) byte {
b1 := in>>4 | in<<4
b2 := b1>>2&0x33 | b1<<2&0xcc
b3 := b2>>1&0x55 | b2<<1&0xaa
return b3
}
func asn1BitLength(bitString []byte) int {
bitLen := len(bitString) * 8
for i := range bitString {
b := bitString[len(bitString)-i-1]
for bit := uint(0); bit < 8; bit++ {
if (b>>bit)&1 == 1 {
return bitLen
}
bitLen--
}
}
return 0
}
你可以这样使用它:
keyUsage := x509.KeyUsage(x509.KeyUsageDigitalSignature)
extKeyUsage, err := marshalKeyUsage(keyUsage)
if err != nil {
log.Fatal(err)
}
// 将此扩展添加到CSR中,如下所示
template.ExtraExtensions = []pkix.Extension{extKeyUsage}
英文:
I'm also not find a nice short way of adding KeyUsage
to my CSRs. I looked into golang's code and found this.
I finally ended up extracting following piece of code:
func marshalKeyUsage(ku x509.KeyUsage) (pkix.Extension, error) {
ext := pkix.Extension{Id: asn1.ObjectIdentifier{2, 5, 29, 15}, Critical: true}
var a [2]byte
a[0] = reverseBitsInAByte(byte(ku))
a[1] = reverseBitsInAByte(byte(ku >> 8))
l := 1
if a[1] != 0 {
l = 2
}
bitString := a[:l]
var err error
ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})
if err != nil {
return ext, err
}
return ext, nil
}
func reverseBitsInAByte(in byte) byte {
b1 := in>>4 | in<<4
b2 := b1>>2&0x33 | b1<<2&0xcc
b3 := b2>>1&0x55 | b2<<1&0xaa
return b3
}
func asn1BitLength(bitString []byte) int {
bitLen := len(bitString) * 8
for i := range bitString {
b := bitString[len(bitString)-i-1]
for bit := uint(0); bit < 8; bit++ {
if (b>>bit)&1 == 1 {
return bitLen
}
bitLen--
}
}
return 0
}
You can use this as:
keyUsage := x509.KeyUsage(x509.KeyUsageDigitalSignature)
extKeyUsage, err := marshalKeyUsage(keyUsage)
if err != nil {
log.Fatal(err)
}
// add this extension to csr like below
template.ExtraExtensions = []pkix.Extension{extKeyUsage}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论