ASN.1基本信息
ASN.1(Abstract Syntax Notation One)是一种国际标准(由ITU-T X.680系列建议定义),用于描述数据的结构。它主要用于定义和编码传输协议中的数据,以确保不同系统间的数据交换。
ASN.1语法可用来描述各种类型的数据,包括文本、图形、视频与音频等。通常用于定义应用数据的抽象语法和PDU的结构。比如SNMP中使用ASN.1进行管理信息结构SMI的定义和管理数据库MIB的定义。ASN.1编码可用来规范数据传输过程,解决异构网络对数据理解的二义性。
ASN.1最初是ITU针对电信协议设计而制定,后来被ISO接受成为国际标准。
ASN.1的主要应用:
-
网络协议:ASN.1被广泛用于各种网络协议,如SNMP(Simple Network Management Protocol)、LDAP(Lightweight Directory Access Protocol)和X.500目录服务。它帮助定义和编码数据,使不同的系统可以互相通信。
-
电信系统:在电信行业,ASN.1用于信令协议,如SS7(Signaling System No. 7)和GSM(Global System for Mobile Communications)。它确保不同电信设备之间的互操作性。
-
安全协议:ASN.1被用于许多安全协议,如X.509数字证书和SSL/TLS。它帮助定义和编码证书、密钥和其他安全相关的数据结构。
-
金融系统:在金融行业,ASN.1用于标准化各种交易和信息交换协议,如ISO 20022标准。这有助于不同金融机构之间的信息交换和处理。
-
多媒体通信:ASN.1还用于多媒体通信协议,如H.323和H.264,用于视频会议、VoIP和其他实时通信应用。
-
智能卡:在智能卡应用中,ASN.1用于定义和传输数据,如在电子护照和支付卡中。
-
数据交换格式:ASN.1可用于定义通用数据交换格式,使不同系统能够理解和处理相同的数据结构。
ASN.1编码规则
ASN.1的广泛应用得益于其灵活性和扩展性,以及它支持多种编码规则,如BER(Basic Encoding Rules)、DER(Distinguished Encoding Rules)和PER(Packed Encoding Rules),以满足不同应用的需求。ASN.1 提供了多种编码规范,以适应不同应用的需求。主要的编码规范包括:
-
BER(Basic Encoding Rules):
- 基本编码规则,是ASN.1的最基本编码规则,灵活且容易实现。
- 使用标签类型(Type)、长度(length)和内容(value)三部分来表示数据。
- BER的灵活性也意味着它可能会生成冗长的编码,不适合对效率要求高的场合。
-
DER(Distinguished Encoding Rules):
- 区别编码规则,是BER的子集,消除了BER中的不确定性,确保了唯一的编码方式。
- 用于需要唯一编码的场合,如数字证书(X.509)和加密协议。
-
CER(Canonical Encoding Rules):
- 规范编码规则,与DER类似,但用于无限长字符串的情况下。
- 通过规范化处理,确保编码的唯一性,适用于一些需要数据一致性的应用。
-
PER(Packed Encoding Rules):
- 紧凑编码规则,通过优化编码来减少数据的长度,适合对带宽敏感的场合。
- 有两种变体:对齐(Aligned PER)和非对齐(Unaligned PER),对齐的编码会以八位字节为单位,而非对齐则不会。
-
XER(XML Encoding Rules):
- XML编码规则,将ASN.1描述的数据结构编码为XML格式,便于与基于XML的系统进行互操作。
- 易于阅读和调试,但比其他编码规则更加冗长。
-
OER(Octet Encoding Rules):
- 八位字节编码规则,旨在提供一种高效且容易解析的编码规则。
- 适用于需要紧凑和快速解析的应用场合。
-
JER(JSON Encoding Rules):
- JSON编码规则,将ASN.1描述的数据结构编码为JSON格式。
- 适用于与基于JSON的系统和应用进行互操作。
ASN.1的关键字
基本类型如:
INTEGER:
- 输出类型:整数
- 解释:表示整数值。
- 十六进制值:0x02
OCTET STRING:
- 输出类型:字节串
- 解释:表示任意长度的字节序列。
- 十六进制值:0x04
NULL:
- 输出类型:空值
- 解释:表示一个空值。
- 十六进制值:0x05
PrintableString:
- 输出类型:可打印字节串
- 解释:表示任意长度的打印字符串。
- 十六进制值:0x13
结构化类型如:
SEQUENCE:
- 输出类型:序列
- 解释:表示一组有序的数据项。
- 十六进制值:0x30
实现
- main.go
package main
import (
"encoding/asn1"
"encoding/hex"
"fmt"
"log"
)
type Person struct {
Name string
Age int
}
func main() {
person := Person{Name: "Alice", Age: 30}
// 编码
data, err := asn1.Marshal(person)
if err != nil {
log.Fatalf("Marshaling failed: %v", err)
}
fmt.Printf("Encoded data: %x\n", data)
fmt.Printf("Hex data: %v\n", hex.Dump(data))
// 解码
var decodedPerson Person
_, err = asn1.Unmarshal(data, &decodedPerson)
if err != nil {
log.Fatalf("Unmarshaling failed: %v", err)
}
fmt.Printf("Decoded person: %+v\n", decodedPerson)
}
- 运行
[xiaofeng@localhost asn]$ go run main.go
Encoded data: 300a1305416c69636502011e
Hex data: 00000000 30 0a 13 05 41 6c 69 63 65 02 01 1e |0...Alice...|
Decoded person: {Name:Alice Age:30}
- 分析
类型|长度|值
- 30 表示序列结构类型
- 0a 长度为10
- 13 表示可打印字符串
- 05 长度为5
- 41 6c 69 63 65 表示值Alice
- 02 表示整数类型
- 01 表示长度为1
- 1e 表示值30