为了账号安全,请及时绑定邮箱和手机立即绑定

来自 x509 证书的 golang 主题 dn

来自 x509 证书的 golang 主题 dn

Go
慕姐4208626 2022-03-03 15:58:29
是否有任何简单的方法可以从 x509 证书中获取完整的主题 DN(或颁发者 DN)作为字符串?我在 pkix.Name 中找不到像“.String()”这样的方法
查看完整描述

3 回答

?
米脂

TA贡献1836条经验 获得超3个赞

解决方案(感谢同事):


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

这似乎是唯一的“简单”解决方案


查看完整回答
反对 回复 2022-03-03
?
噜噜哒

TA贡献1784条经验 获得超7个赞

为了从 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()

同样,如果您只需要从主题(或发行者)获取某些特定的对象值,您可以使用下一种方法。下面的示例从主题中检索 UID(未在标准库https://github.com/golang/go/issues/25667中定义)


// 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)


查看完整回答
反对 回复 2022-03-03
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

我今天面临同样的任务。您可以通过这种方式从证书中获取主题:


// 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


查看完整回答
反对 回复 2022-03-03
  • 3 回答
  • 0 关注
  • 308 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信