米脂
解决方案(感谢同事):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这似乎是唯一的“简单”解决方案
噜噜哒
为了从 x509 证书中获取完整的主题 DN(或颁发者 DN),您可以使用下一个代码:cert, err := x509.ParseCertificate(certData)if err != nil { return err}var subject pkix.RDNSequenceif _, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil { return err}fmt.Plrintln(subject.String()同样,如果您只需要从主题(或发行者)获取某些特定的对象值,您可以使用下一种方法。下面的示例从主题中检索 UID(未在标准库https://github.com/golang/go/issues/25667中定义)// http://www.alvestrand.no/objectid/0.9.2342.19200300.100.1.1.htmlconst oidUserID = "0.9.2342.19200300.100.1.1"var UID stringcert, 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/25667var subject pkix.RDNSequenceif _, 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.htmlvar oidUserID = []int{0, 9, 2342, 19200300, 100, 1, 1}var UID stringcert, err := x509.ParseCertificate(certData)if err != nil { return err}// reading the UID from list of unprased // objects from Subjectfor _, n := range cert.Subject.Names { if n.Type.Equal(oidUserID) { if v, ok := n.Value.(string); ok { UID = v } }}fmt.Println(UID)