来自几年前本人写的一篇博客 http://blog.csdn.net/newyf_cun/article/details/13016069
如下使用libtasn1分析asn1的编码规则。
http://www.linuxfromscratch.org/blfs/view/stable/general/libtasn1.html
https://github.com/Distrotech/libtasn1
http://www.gnu.org/software/libtasn1/
0.ASN.1的编码规则:
8 7 6 5 4 3 2 1 + Length + Content ------------------------------------------------------------------------- |Class |X | Tag | | ------------------------------------------------------------------------- Class: 0 0 Universal 0 1 Application 1 0 Context-speciatic:指Type不需传送,双方约定 IMPLICIT1 1 prviate X : 0 ---- primitive -----指定:content without a Structure 只有 1个Length 1个Content 1 ---- contructed -----指定:content with addition structure (如squence,squence of , implicit squence ,implicit squence of ) (Type , Length ,Content )任意个嵌套T-L-C。 Tag: ASN.1中Tag可能超过5个Bits,但是MMS中不会出现 Length: 指Content的长度。
1. 创建模板文件
bash-2.05$ cat tpl.asn PKIX1 { } DEFINITIONS IMPLICIT TAGS ::= BEGIN Dss-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } END
分析:定义一个结构体,含有两个整形变量r和s。
2. 创建模板值文件
bash-2.05$ cat value.asn dp PKIX1.Dss-Sig-Value r 4243 s 4748
分析:赋值文件,将r赋值为十进制4243,s赋值十进制4748
3. 将以上模板和值文件asn1编码
bash-2.05$ ./asn1Coding tpl.asn value.asn Parse: done. var=dp, value=PKIX1.Dss-Sig-Value var=r, value=4243 var=s, value=4748 name:NULL type:SEQUENCE name:r type:INTEGER value:0x1093 name:s type:INTEGER value:0x128c Coding: SUCCESS ----------------- Number of bytes=10 30 08 02 02 10 93 02 02 12 8c ----------------- OutputFile=value.out Writing: done.
分析:asn编码后的数据是30 08 02 02 10 93 02 02 12 8c
其中:十六进制30 = 二进制0011 0000, 表示通用模式(00)的结构体(1)定义(二进制10000=十六进制10) #define ASN1_TAG_SEQUENCE0x10;
08表示长度为8,即02 02 10 93 02 02 12 8c的长度正好是8;
02 02 10 93是变量r的类型02(整形#define ASN1_TAG_INTEGER0x02)-长度(02,即值10 93的长度)-和值(十六进制10 93转成十进制为4243);
02 02 12 8c是变量s的类型02(整形#define ASN1_TAG_INTEGER0x02)-长度(02,即值12 8c的长度)-和值(十六进制12 8c转成十进制为4748);
4. 将以上输出asn1解码
bash-2.05$ ./asn1Decoding tpl.asn value.out PKIX1.Dss-Sig-Value Parse: done. Decoding: SUCCESS DECODING RESULT: name:NULL type:SEQUENCE name:r type:INTEGER value:0x1093 name:s type:INTEGER value:0x128c
分析:文件value.out中保存着3008020210930202128c
按照模板tpl.asn解码结构体PKIX1.Dss-Sig-Value得到变量r和s的值。
5. 将asn模板文件转成c代码
bash-2.05$ ./asn1Parser tpl.asn Done. bash-2.05$ cat tpl tpl.asn tpl_asn1_tab.c bash-2.05$ cat tpl_asn1_tab.c #if HAVE_CONFIG_H # include "config.h" #endif #include <libtasn1.h> const asn1_static_node tpl_asn1_tab[] = { { "PKIX1", 536875024, NULL }, { NULL, 1073741836, NULL }, { "Dss-Sig-Value", 536870917, NULL }, { "r", 1073741827, NULL }, { "s", 3, NULL }, { NULL, 0, NULL } };