You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Golang中从SAN内指定OID检索对应存储值的方法

从X.509证书subjectAltName扩展中提取指定OID对应值

你已经通过代码定位到了X.509证书的subjectAltName扩展,接下来可以通过以下步骤提取OID 2.23.33.5.1.6对应的UTF8String值:

核心思路

subjectAltName扩展的extnValue是一个SEQUENCE,内部以OID + 对应值的成对形式存储数据。我们需要将extensionData的内容进一步反序列化为ASN.1原始值切片,然后遍历切片,匹配目标OID后提取对应的值。

完整代码实现

import (
	"crypto/x509/pkix"
	"encoding/asn1"
	"log"
)

var subjectAltNameOID = []int{2, 5, 29, 17}
var targetOID = asn1.ObjectIdentifier{2, 23, 33, 5, 1, 6}

func extractTargetValue(certificate *pkix.Certificate) (string, error) {
	for _, ext := range certificate.Extensions {
		if ext.Id.Equal(subjectAltNameOID) {
			var extensionData asn1.RawValue
			_, err := asn1.Unmarshal(ext.Value, &extensionData)
			if err != nil {
				return "", err
			}

			// 反序列化extensionData的内容为RawValue切片
			var rawValues []asn1.RawValue
			_, err = asn1.Unmarshal(extensionData.Bytes, &rawValues)
			if err != nil {
				return "", err
			}

			// 遍历成对的OID和值(步长为2)
			for i := 0; i < len(rawValues); i += 2 {
				// 解析当前OID
				var currentOID asn1.ObjectIdentifier
				err = asn1.Unmarshal(rawValues[i].FullBytes, &currentOID)
				if err != nil {
					continue
				}

				// 匹配目标OID
				if currentOID.Equal(targetOID) {
					// 解析对应的UTF8String值
					var value string
					err = asn1.Unmarshal(rawValues[i+1].FullBytes, &value)
					if err != nil {
						return "", err
					}
					return value, nil
				}
			}

			return "", nil // 未找到目标OID
		}
	}
	return "", nil // 未找到subjectAltName扩展
}

关键说明

  1. 反序列化切片:extensionData.Bytes存储了SEQUENCE的原始字节,需要反序列化为[]asn1.RawValue来逐个处理内部元素。
  2. 成对遍历:因为数据是OID与值一一对应的,所以遍历步长设为2,每次处理一组OID和对应值。
  3. OID匹配:将RawValue解析为asn1.ObjectIdentifier后,用Equal方法对比目标OID。
  4. 值解析:匹配成功后,将下一个RawValue解析为string(对应ASN.1的UTF8String类型)。

内容的提问来源于stack exchange,提问作者ray an

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:17:06