有没有简单的方法可以从x509证书中获取完整的主题DN(或颁发者DN)作为字符串?
我无法在pkix.Name
中找到任何类似“.String()”的方法答案 0 :(得分:6)
解决方案(感谢同事):
var oid = map[string]string{
"2.5.4.3": "CN",
"2.5.4.4": "SN",
"2.5.4.5": "serialNumber",
"2.5.4.6": "C",
"2.5.4.7": "L",
"2.5.4.8": "ST",
"2.5.4.9": "streetAddress",
"2.5.4.10": "O",
"2.5.4.11": "OU",
"2.5.4.12": "title",
"2.5.4.17": "postalCode",
"2.5.4.42": "GN",
"2.5.4.43": "initials",
"2.5.4.44": "generationQualifier",
"2.5.4.46": "dnQualifier",
"2.5.4.65": "pseudonym",
"0.9.2342.19200300.100.1.25": "DC",
"1.2.840.113549.1.9.1": "emailAddress",
"0.9.2342.19200300.100.1.1": "userid",
}
func getDNFromCert(namespace pkix.Name, sep string) (string, error) {
subject := []string{}
for _, s := range namespace.ToRDNSequence() {
for _, i := range s {
if v, ok := i.Value.(string); ok {
if name, ok := oid[i.Type.String()]; ok {
// <oid name>=<value>
subject = append(subject, fmt.Sprintf("%s=%s", name, v))
} else {
// <oid>=<value> if no <oid name> is found
subject = append(subject, fmt.Sprintf("%s=%s", i.Type.String(), v))
}
} else {
// <oid>=<value in default format> if value is not string
subject = append(subject, fmt.Sprintf("%s=%v", i.Type.String, v))
}
}
}
return sep + strings.Join(subject, sep), nil
}
调用函数:
subj, err := getDNFromCert(x509Cert.Subject, "/")
if err != nil {
// do error handling
}
fmt.Println(subj)
输出(示例):
/C=US/O=some organization/OU=unit/CN=common name
这似乎是唯一的&#34; easy&#34;溶液
答案 1 :(得分:1)
我今天面临同样的任务。你可以通过这种方式从证书中获得主题:
// d is []byte with your certificate
cert, err := x509.ParseCertificate(d)
fmt.Printf("%+v\n", cert.Subject.ToRDNSequence())
// Output: CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US
答案 2 :(得分:1)
要从x509证书中获取完整的主题DN(或颁发者DN),您可以使用下一个代码:
cert, err := x509.ParseCertificate(certData)
if err != nil {
return err
}
var subject pkix.RDNSequence
if _, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil {
return err
}
fmt.Plrintln(subject.String()
同样,如果您只需要从主题(或发行人)获得某些特定的对象值,您可以使用下一种方法。下面的示例从subject(未在stdlib https://github.com/golang/go/issues/25667中定义)
中检索UID// http://www.alvestrand.no/objectid/0.9.2342.19200300.100.1.1.html
const oidUserID = "0.9.2342.19200300.100.1.1"
var UID string
cert, err := x509.ParseCertificate(certData)
if err != nil {
return err
}
// manually parsing the Certificate subject to get the
// UID field, which is being ignored by the stdlib
// https://github.com/golang/go/issues/25667
var subject pkix.RDNSequence
if _, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil {
return err
}
for _, s := range subject {
for _, i := range s {
if i.Type.String() == oidUserID {
if v, ok := i.Value.(string); ok {
UID = v
}
}
}
}
fmt.Println(UID)
<强>更新强>: 感谢@FiloSottile:
,简化了获取UID的方法// http://www.alvestrand.no/objectid/0.9.2342.19200300.100.1.1.html
var oidUserID = []int{0, 9, 2342, 19200300, 100, 1, 1}
var UID string
cert, err := x509.ParseCertificate(certData)
if err != nil {
return err
}
// reading the UID from list of unprased
// objects from Subject
for _, n := range cert.Subject.Names {
if n.Type.Equal(oidUserID) {
if v, ok := n.Value.(string); ok {
UID = v
}
}
}
fmt.Println(UID)
答案 3 :(得分:0)
直接使用
fmt.Sprintf("%+v", cert.Subject.ToRDNSequence())
在1.9中完成工作。 对于高级版本的go(> = 1.10),它可以与pkix.Name中的“ .String()”一起使用
答案 4 :(得分:0)
现在您可以使用:
cert, _ := x509.ParseCertificate(certDERBlock.Bytes)
fmt.Println(cert.Subject.CommonName)
https://golang.org/pkg/crypto/x509/#Certificate
https://golang.org/pkg/crypto/x509/pkix/#Name
答案 5 :(得分:0)
这是我使用的功能。
date_month
这是获取RDNSequence的代码。该示例获取主题名称。
channel
答案 6 :(得分:0)
这是我最终用来直接解析字符串的函数,而没有使用任何go内部库。
if (document.getElementById('element-id')) {
// if exist must do something }