文章

ASN1

ASN1

该文主要介绍 ASN1。

ASN1

1. ASN1

ASN.1(Abstract Syntax Notation One) 是 ISOITU-T 的联合标准,最初是 1984 年的 CCITT X.409:1984 的一部分。由于其广泛应用,1988 年 ASN.1 移到独立标准 X.208,1995 年进行全面修订后变成 X.680 系列标准。

ASN.1 本身只定义了表示信息的抽象句法,但是没有限定其编码的方法。各种 ASN.1 的编码规则提供了由 ASN.1 描述其抽象句法的数据的值的传送语法(具体表达)。标准的 ASN.1 编码规则有:

  • 基本编码规则(BER,Basic Encoding Rules)
  • 规范编码规则(CER,Canonical Encoding Rules)
  • 唯一编码规则(DER,Distinguished Encoding Rules)
  • 压缩编码规则(PER,Packed Encoding Rules)
  • XML编码规则(XER,XML Encoding Rules)

1.1. TLV编码

TLV (Tag-Length-Value)

1.1.1. Tag (标签)

  • 目的:标识数据类型。
  • 格式:通常为一个字节或多个字节。
  • 结构
    • Class:2 位,用于表示数据类型的类别。有四种类别:
      • 00: Universal (通用类型)
      • 01: Application (应用类型)
      • 10: Context-specific (上下文特定类型)
      • 11: Private (私有类型)
    • PC (Primitive/Constructed):1 位,表示数据是原始类型还是构造类型。
      • 0: Primitive (原始类型)
      • 1: Constructed (构造类型)
    • Tag Number:5 位或更多位,用于表示具体的数据类型。标准类型为 5 位,扩展类型可以使用更多位。

1.1.2. Length (长度)

  • 目的:表示数据值部分的长度。
  • 格式:一个字节或多个字节。
  • 结构
    • 如果第一个字节的最高位为 0,表示短格式,用 7 位表示长度(0-127)。
    • 如果第一个字节的最高位为 1,表示长格式,低 7 位表示后续字节数。后续字节表示的值为数据值的实际长度。即 0x81 表示 1 字节,0x82 表示 2 字节,0x83 表示 3 字节,0x84 表示 4 字节

1.1.3. Value (值)

  • 目的:存储实际的数据。
  • 格式:任意长度,由 Length 字段定义。
  • 结构:具体的数据,根据 Tag 字段定义的类型进行编码。

1.2. Tag类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* ASN.1 tag values */
#define EASY_ASN1_EOC               0x0
#define EASY_ASN1_BOOLEAN           0x1
#define EASY_ASN1_INTEGER           0x2
#define EASY_ASN1_BIT_STRING        0x3
#define EASY_ASN1_OCTET_STRING      0x4
#define EASY_ASN1_NULL              0x5
#define EASY_ASN1_OBJECT            0x6
#define EASY_ASN1_OBJECT_DESCRIPTOR 0x7
#define EASY_ASN1_EXTERNAL          0x8
#define EASY_ASN1_REAL              0x9
#define EASY_ASN1_ENUMERATED        0xA
#define EASY_ASN1_EMBEDDED_PDV      0xB
#define EASY_ASN1_UTF8STRING        0xC
#define EASY_ASN1_RELATIVE_OID      0xD
#define EASY_ASN1_TIME              0xE
#define EASY_ASN1_SEQUENCE          0x10
#define EASY_ASN1_SET               0x11
#define EASY_ASN1_NUMERICSTRING     0x12
#define EASY_ASN1_PRINTABLESTRING   0x13 /* printable subset of ascii */
#define EASY_ASN1_T61STRING         0x14
#define EASY_ASN1_TELETEXSTRING     0x14 /* alias */
#define EASY_ASN1_VIDEOTEXSTRING    0x15
#define EASY_ASN1_IA5STRING         0x16 /* 7-bit ascii */
#define EASY_ASN1_UTCTIME           0x17
#define EASY_ASN1_GENERALIZEDTIME   0x18
#define EASY_ASN1_GRAPHICSTRING     0x19
#define EASY_ASN1_ISO64STRING       0x1A
#define EASY_ASN1_VISIBLESTRING     0x1A /* alias */
#define EASY_ASN1_GENERALSTRING     0x1B
#define EASY_ASN1_UNIVERSALSTRING   0x1C
#define EASY_ASN1_CHARACTER_STRING  0x1D
#define EASY_ASN1_BMPSTRING         0x1E /* 2-byte unicode with zeros */

2. 代码实现

https://github.com/august295/EnDeCode

参考

本文由作者按照 CC BY 4.0 进行授权