如何使用Golang encoding/asn1解析ASN.1自定义标签?
如何使用Golang encoding/asn1解析ASN.1自定义标签?
别担心,我来给你一步步说清楚怎么用Go的encoding/asn1包解析带自定义标签的ASN.1数据,拿到那个[1]标签并处理它的内容:
首先,你已经通过asn1.Marshal得到了带自定义标签的ASN.1字节数组b,现在要把它解析成asn1.RawValue来保留标签信息其实很简单——因为asn1.RawValue会完整保留ASN.1元素的标签、类别、原始字节这些关键信息,不会直接把值解析成具体类型,正好满足你查看标签的需求。
第一步:解析外层SEQUENCE到RawValue切片
你用dumpasn1看到的最外层是SEQUENCE结构,所以我们可以直接把字节数组解析成[]asn1.RawValue,这样SEQUENCE里的每一个元素都会变成一个RawValue实例,标签信息就存在Tag字段里:
package main import ( "encoding/asn1" "fmt" ) type V struct { S int `asn1:"tag:1"` } func main() { // 复现你生成字节数组的过程 val := V{S: 12} b, _ := asn1.Marshal(val) // 解析成[]asn1.RawValue,获取每个元素的标签信息 var rawElements []asn1.RawValue _, err := asn1.Unmarshal(b, &rawElements) if err != nil { panic(err) } // 遍历每个RawValue,查看标签并处理内容 for _, rv := range rawElements { fmt.Printf("找到自定义标签: [%d]\n", rv.Tag) fmt.Printf("标签对应的原始字节: %x\n", rv.Bytes) // 如果要把原始字节解析回int类型 var s int _, err := asn1.Unmarshal(rv.Bytes, &s) if err != nil { panic(err) } fmt.Printf("解析出的具体值: %d\n", s) } }
第二步:理解RawValue的关键字段
asn1.RawValue里几个对你有用的核心字段:
Tag: 就是你在dumpasn1里看到的[1]中的数字1,也就是自定义标签的编号Bytes: 标签对应的值的原始字节,你可以把它再解析成具体的Go类型(比如int、string等)Class: 表示标签的类别,这里你的自定义标签属于上下文特定类,对应asn1.ClassContextSpecificIsCompound: 标记这个元素是否是复合类型(比如SEQUENCE、SET),这里你的int值是简单类型,所以是false
进阶:不确定外层结构时的处理
如果你不确定最外层的ASN.1结构,也可以先解析成一个单独的asn1.RawValue,先判断它是不是SEQUENCE,再解析内部元素:
var outerRaw asn1.RawValue _, err := asn1.Unmarshal(b, &outerRaw) if err != nil { panic(err) } // 确认外层是SEQUENCE(ASN.1中SEQUENCE的通用标签编号是16) if outerRaw.Tag == asn1.TagSequence { var innerElements []asn1.RawValue _, err := asn1.Unmarshal(outerRaw.Bytes, &innerElements) if err != nil { panic(err) } // 接下来就可以像之前一样处理innerElements里的自定义标签了 }
这样一来,你就能轻松拿到自定义标签的信息,再根据自己的需求处理对应的值啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

