【问题标题】:How to extract common name from distinguished name using Go?如何使用 Go 从专有名称中提取通用名称?
【发布时间】:2018-07-11 22:11:31
【问题描述】:

我有一个来自 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.)。

【问题讨论】:

标签: parsing go openssl cryptography x509


【解决方案1】:

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

这是一个使用正则表达式的示例。 警告:不能保证这在所有情况下都有效。例如,我看到过小写 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.]

【讨论】:

  • 我不相信 “... 主题或发行人 [专有名称] 不应该被传递和解析,它纯粹是为了人类方便。” 是正确的。如果有效地成为目录或数据库的键,则可分辨名称。它用于唯一标识实体或对象。另请参阅RFC 4514
  • 您的回答中包含的警告“不能保证这在所有情况下都有效”,这是我试图通过要求一个经过良好测试的包来为我做这件事来避免的。不过感谢您的宝贵时间。
  • 我不知道 Go 中有任何库可以为您执行此操作。在 SO 上寻求图书馆推荐也是题外话。
【解决方案2】:

如果您只有以下字符串,这是我为解决此问题而编写的一个函数,例如: 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-02
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多