如何使用Go?

时间:2018-02-01 14:35:41

标签: parsing go openssl cryptography x509

我从X.509证书中获得了x509证书的主题专有名称(DN)。我想从中提取通用名称(CN)。有没有办法通过crypto/x509或Go中的任何其他库来实现?

例如,如果主题的专有名称是:

CN=AMA AMI SA APB MDE MADB MDS LE.AXVD-04954-19-17.,OU=Abc,O=DA.CB.AcbDinema.com,dnQualifier=PY0aT8abfcQeUyquTe4w5RVasfY=

然后我想从中提取公共名称(CN)部分(AMA AMI SA APB MDE MADB MDS LE.AXVD-04954-19-17.)。

2 个答案:

答案 0 :(得分:1)

Go标准库中没有任何内容可以为您解析它(它只处理ASN.1编码的专有名称),但您只将其视为字符串并自行解析。

以下是使用regexp的示例。 警告语:无法保证在所有情况下都能正常使用。例如,我发现了小写CN的情况,或者排序可能会发生变化,或者只是格式错误。

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    subjectString := "CN=AMA AMI SA APB MDE MADB MDS LE.AXVD-04954-19-17.,OU=Abc,O=DA.CB.AcbDinema.com,dnQualifier=PY0aT8abfcQeUyquTe4w5RVasfY="
    re := regexp.MustCompile("CN=([^,]+)")
    matches := re.FindStringSubmatch(subjectString)

    fmt.Println(matches[1])

    commonNameParts := strings.Split(matches[1], " ")
    fmt.Println(commonNameParts)
}

输出完整的CN字符串和CommonName的各个组件的片段:

AMA AMI SA APB MDE MADB MDS LE.AXVD-04954-19-17.
[AMA AMI SA APB MDE MADB MDS LE.AXVD-04954-19-17.]

答案 1 :(得分:1)

这是我编写的用于解决此问题的函数,如果您只有以下字符串: C=US, O="Cloudflare, Inc.", CN=Cloudflare Inc ECC CA-3

func parseIssuerDn(issuer string) map[string]string {

    trackerResultMap := map[string]string{"C=": "", "O=": "", "CN=": "", "ST=": "", "L=": "", "OU=": ""}

    for tracker, _ := range trackerResultMap {
        index := strings.Index(issuer, tracker)

        if index < 0 {
            continue
        }

        var res string

        // track quotes for delimited fields so we know not to split on the comma
        quoteCount := 0

        for i := index + len(tracker); i < len(issuer); i++ {

            char := issuer[i]

            // if ", we need to count and delimit
            if char == 34 {
                quoteCount++
                if quoteCount == 2 {
                    break
                } else {
                    continue
                }
            }

            // comma, lets stop here but only if we don't have quotes
            if char == 44 && quoteCount == 0 {
                break
            }

            // add this individual char
            res += string(rune(char))

        }

        trackerResultMap[strings.TrimSuffix(tracker, "=")] = strings.TrimPrefix(res, "=")
    }

    for k, v := range trackerResultMap {
        if len(v) == 0 {
            delete(trackerResultMap, k)
        }
    }

    return trackerResultMap
}