ASN1编码.docx

上传人:b****3 文档编号:10400132 上传时间:2023-05-25 格式:DOCX 页数:14 大小:95.44KB
下载 相关 举报
ASN1编码.docx_第1页
第1页 / 共14页
ASN1编码.docx_第2页
第2页 / 共14页
ASN1编码.docx_第3页
第3页 / 共14页
ASN1编码.docx_第4页
第4页 / 共14页
ASN1编码.docx_第5页
第5页 / 共14页
ASN1编码.docx_第6页
第6页 / 共14页
ASN1编码.docx_第7页
第7页 / 共14页
ASN1编码.docx_第8页
第8页 / 共14页
ASN1编码.docx_第9页
第9页 / 共14页
ASN1编码.docx_第10页
第10页 / 共14页
ASN1编码.docx_第11页
第11页 / 共14页
ASN1编码.docx_第12页
第12页 / 共14页
ASN1编码.docx_第13页
第13页 / 共14页
ASN1编码.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

ASN1编码.docx

《ASN1编码.docx》由会员分享,可在线阅读,更多相关《ASN1编码.docx(14页珍藏版)》请在冰点文库上搜索。

ASN1编码.docx

ASN1编码

ASN.1编码

1.什么是ASN.1(抽象语法记法一)?

       ASN.1是ITU-T的一个标准集,它用来编码及表示通用数据类型,这些数据类型有可打印串值,八位位组串值,位串值,整数值以及用可移值方式组合而成的其他类型序列值.简单的说,ASN.1指定了以何种方式对非平凡的数据类型进行编码,以便其他任何平台及第三方工具都能够解释其内容.比如,字母a在一些平台以ASCII编码为十进制数值97,而在其他非ASCII平台上,可能会是另外的编码.而ASN.1指定了一种编码方式,在任何平台上,字母a的编码都是统一的.

 

 

2.ASN.1语法.

       ASN.1语法遵循传统的巴科斯范式BNF风格.最基本的表达式如:

 Name:

:

=type.表示为定义某个名称为Name的元素,它的类型为type. 例如:

 MyName:

:

=IA5String.表示为定义了一个名为MyName的元素或变量,其类型为ASN.1类型IA5String(类似于ASCII字符串).

 

2.1 ASN.1显式值(ExplictValue).

  有些时候,我们需要定义一种ASN.1类型,它的子集元素包含预定义值. Name:

:

=type(ExplictValue). 显式值(ExplictValue).必须是ASN.1类型允许选择的值,而且也必须是元素所允许的值.例:

MyName:

:

=IA5String(Tom)表示MyName是字符串Tom的IA5String编码. 又例如:

MyName:

:

=IA5String(Tom|Joe)表示字符串的值既可以是Tom,也可以是Joe.

       这种语法的使用是为了扩展确定的解码器.例:

        PublicKey:

:

=SEQUENCE{

           KeyType      BOOLEAN(0),

           Modulus       INTEGER,

           PubExponentINTEGER

        }

 

       PrivateKey:

:

=SEQUENCE{

           KeyType      BOOLEAN

(1)

           Modulus        INTEGER,

           PubExponent INTEGER,

           PrivateExponentINTEGER

         }

 

2.2 ASN.1容器(container)

        容器是值一个包含了其他相同或者不同类型元素的数据类型(例如序列值SEQUENCE或集合值SET类型).目的是为了组合一些复杂的数据类型集.ASN.1规范定义了4种容器类型:

序列,单一序列(SEQUENCEOF),集合和单一集合(SETOF).虽然它们意义不同,但是语法是一样的.

       Name:

:

=Container{NameType[NameType...]}  方括号中的内容和容器的元素个数都是可选项.还可以进行嵌套定义.

例:

  UserRecord:

:

=SEQUENCE{

          Name  SEQUENCE{

              FirstIA5String,

              Last IA5String

           },

          DoB    UTCTIME

       }

将其粗略的翻译成C语言中的结构如下:

  structUserRecord{

          structName{

            char*First,

            char*Last

          };

         time_tDoB;

       }

将其粗略的翻译成ObjectPascal语言中的记录如下(ObjectPascal不支持嵌套记录):

      Type

           Name=record

             First:

String;

             Last :

String;

           end;

           UserRecord=record

             aName:

Name;

             DoB   :

DateTime;

           end;

 

2.3ASN.1修改器

       ASN.1定义了各种修改器,如可选(OPTIONAL),默认(DEFAULT),和选择(CHOICE).他们可以改变表达式的声明.典型地用于定义一种要求编码灵活,而定义又不繁琐的类型.

      <1>.可选(OPTIONAL)。

顾名思义,其表示改变一个元素以便在编码时它的类型是可选择的.即编码器可以忽略这个元素,解码器不能假设它将出现.但当邻接的两个元素具有相同的类型时,会给解码器带来一些问题.

       定义:

Name:

:

=TypeOPTIONAL

  例如:

     Float:

:

=SEQUENCE{

                                        Exponent    INTEGEROPTIONAL,

                                        Mantissa    INTEGER,

                                        Sign            BOOLEAN

                       }

        当解码器读取这个结构时,在它看来第一个整数(INTEGER)可能是Exponent,也有可能认为是Mantissa. 一般建议不使用这种方式定义结构.

  <2>.默认(DEFAULT).默认修改器允许容器包含默认值.如果待编码的数据值等同于它的默认值,那么它将在发送的数据流中被忽略.例如:

     Command:

:

=SEQUENCE{

                                        Token        IA5String(NOP)DEFAULT,

                                        Parameter  INTEGER

                      }

        如果编码器把Token看成是代表字符串NOP,那么序列将按照定义的那样编码为:

                     Command:

:

=SEQUENCE{

                                       Parameter   INTEGER

                     }

       <3>.选择(CHOICE).选择修改器允许一个元素在给定的实例中可以有多个可能值.实质上说,解码器将尝试所有期望的解码算法,直到有一个类型符合为止.当一个复杂的容器中包含其他容器时,时候选择器就十分有用了.例如:

     UserKey:

:

=SEQUENCE{

                                      Name            IA5String,

                                      StartDate      UTCTIME,

                                      Expire           UTCTIME,

                                      KeyData       CHOICE{

                                             ECCKey       ECCKeyType,

                                             RSAKey       RSAKeyType

                                      }

                       }

        上例简单的允许ECC也允许RSA密钥的公钥证书.

 

3.ASN.1数据类型

       ASN.1针对广泛的应用定义了多种数据类型,我们这里只讨论跟密码学应用相关的数据类型.我们将讨论如下数据类型:

∙ 

▪  布尔型(Boolean);

▪       八位位组串(OCTETString);

▪       位串(BITString);

▪       IA5String;

▪       可打印字符串(PrintableString);

▪       整数(INTEGER);

▪       对象标识符(OBJECTIdentifier,OID);

▪       世界协调时(UTCTIME);

▪       空(NULL);

▪       序列,单一序列;

▪       集合;

▪       单一集合;

 

  任何ASN.1编码都是以两个字节开始(或者八位位组,含有8个二进制位),不管什么类型,它们都是通用的.第一个字节是类型标识符,也包含一些修正位;第二各字节是长度.

 

3.1ASN.1头字节

     头字节(hearderbyte)位于ASN.1编码的开始,由3部分组成。

如下图:

    

       <1>.类别位。

                类别位(classificationbits)由两位表示,用来描述数据将要解释的上下文。

                  

位8

位7

类别

0

0

通用(Universal)

0

1

应用(Application)

1

0

上下文特定(ContextSpecific)

1

1

专用(Private)

 

                 所有的类型中,通用类别最常用。

       <2>.结构化位。

               结构化位(constructedbit)表示一个给定的编码是否是相同类型的多种编码的结构化。

结构化元素是容器类型必需的,因为在逻辑上,它们只是其他元素的集合。

               结构化元素有自己的头字节和长度字节,之后是元素各个要素组件的单独编码。

也就是说,这些要素组件是独立地可解码ASN.1数据类型。

              严格的说,容器类是唯一允许使用结构化位的数据类型。

这是因为对于其他数据类型,给定内容,只允许一种编码。

所以其他所有数据类型的结构化位都为0。

     <3>.原始类型。

              ASN.1头字节的低5位定义了32种ASN.1的原始类型(primitivetype)

 

代码

ASN.1类型

作用

1

布尔型

储存布尔值

2

整数

储存大整数

3

位串

存储位数组

4

八位位串

存储字节数组

5

预留位(例如在选择修改器中)

6

对象标识符

标识算法及协议

16

序列和单一序列

未分类元素的容器

17

集合和单一集合

已分类元素的容器

19

可打印字符串

ASCII编码(忽略一些不可打印字符)

22

IA5String

ASCII编码

23

世界协调时

以统一格式表示的时间

 

3.2ASN.1长度编码

根据编码的实际长度,ASN.1定义了两种长度编码(lengthencoding)方法,长编码和短编码。

编码字节的最高位代表的是短编码还是长编码;而低7位则形成一个长度立即数。

<1>.短编码。

       在短编码中,负载的长度必须小于128字节。

长度立即数用来表示负载的长度。

例如,对于一个长度为65(0x41)的负载进行编码,其长度编码字节只需简单的设置为0x41即可。

因为其最高位是0,则编码器可以判断出这是短编码,而且长度是65。

<2>.长编码。

       在长编码中,定义了附加的抽象数据来对长度进行编码,它仅适用于所有长度为128字节或以上的负载。

在这种模式下,长度立即数存储的是为了表示负载长度所需的字节数。

这个长度必须以big-endian格式进行编码。

(其实bigendian是指低地址存放最高有效字节(MSB),而littleendian则是低地址存放最低有效字节(LSB)。

)。

        例如,为一个长度为47310(0xB8CE)的负载进行编码,因为它的长度大于127,所以要采用长编码方式。

实际的长度需要两个字节来表示。

则,长度编码字节为0x82;然后用big-endian格式存储的长度值为0xB80xCE。

则全部长度编码为0x82B8CE。

 

3.3ASN.1布尔类型

     布尔编码的负载或者是全0或者是全1的八位位组。

头字节以0x01开始,长度编码字节为0x01,负载内容取决于布尔值的取值。

布尔值

编码

False

0x010100

True

0x0101FF

 

3.4ASN.1整数类型

     整数类型表示一个有符号的任意精度的标量,它的编码是可移植,平台无关的。

     正整数的编码比较简单。

每个字节表示的最大整数是255(0xFF),存储的实际数值分成字节大小的数字,并且以big-endian格式存储。

例如:

八位位组{Xk,Xk-1,....,X0}将以递减的顺序从Xk到X0进行存储.编码规定正整数的第一个字节的最高位必须是0,即Xk的最高为必须是0,为1的话则为负数.例如:

 x=49468=193*256+60=0xC1*0xFF+0x3C;即X1=0xC1,X0=0x3C.按正常规定,编码应该是0x0202C13C,但是X1的最高位是1,应该被看成负数.最简单的方法是用前端零字节进行填充.编码变为0x020200C13C.

 负整数的编码有些复杂.要先找到一个最小的256的幂,使它比要编码的负数的绝对值还要大.例如:

x=-1555;被1555大的256的最小的幂是256^2=65536;然后将这个数跟负数相加以得到2的补码.65536+(-1555)=63981= 0xF9*0xFF+0xED.则编码为0x0202F9ED.

     以下是一些常用整数编码的例子.

编码

0

0x020100

1

0x020101

2

0x020102

127

0x02017F

128

0x02020080

-1

0x0201FF

-128

0x020180

-32768

0x02028000

1234567890

0x0204499602D2

 

3.5ANS.1位串类型

     位串(BITSTRING)类型以可移植形式表示位数组.除了ASN.1头部两个字节之外,还有一个附加的头部用来表示填充数据(通常是一个字节,因为填充是为了形成一个完整的字节).编码规则:

位串的第一位放到第一个负载字节的第8位;位串的第二位放到第一个负载字节的第7位;依此类推.填充满第一个负载字节,就继续填充第二个负载字节.如果最后一个负载字节未被填充满,空的位用0来填充,0的个数存放到头部用来表示填充数据的那个字节里.

下面举例说明:

有一个位串{1,0,0,0,1,1,1,0,1,0,0,1},开始填充负载字节.第一个字节填充后为10001110=0x8E;第二个字节填充后为10010000=0x90,低位4个0为填充的空位.则,负载为2个字节加上表示填充0个数的一个字节0x04总共3个字节.则完整的编码为:

0x0303048E90.

 

解码器通过计算8*负载长度-填充数来得到存储输出所需要的位数.

 

3.6ASN.1八位位组串类型

 八位位组串(OCTETSTRING)是保存字节数组,它和位串类型(BITSTRING)很相似.这种编码非常简单,像其他类型一样对头部进行编码,然后直接将八位位组复制过去即可.例如:

对{FE,ED,6A,B4}编码;首先存储类型0x04,接着是长度0x04,然后是字节本身0xFEED6AB4;完整的编码为0x0404FEED6AB4.

 

3.7空类型

    空(NULL)类型实际上是"占位符",它是含有空白选项的选择修改器所特有.例如:

         MyAccount:

:

=SEQUENCE{

                   Name                           IA5String,

                   Group                          IA5String,

                   Credentials                   CHOICE{

                                                             rsaKey          RSAPublicKey,

                                                             passwdHash OCTETSTRING,

                                                             none              NULL

                                                        }

          }

    在上面这个结构中,帐号的证书应该包含一个RSA密钥或一个密码散列值或什么都没有.

 空类型的编码是0x0500.

 

3.8ASN.1对象标识符类型

     对象标识符(OBJECTIDENTIFIER,OID)类型用层次的形式来表示标准规范.标识符树通过一个点分的十进制符号来定义,这个符号以组织,子部分然后是标准的类型和各自的子标识符开始.

     例如:

MD5的OID是1.2.840.113549.2.5 表示为"iso

(1)member-body

(2)US(840)rsadsi(113549)digestAlgorithm

(2)md5(5)",所以当解码程序看到这个OID时,就知道是MD5散列.

     OID在公钥算法标准中很流行,它指出证书绑定了哪种散列算法.同样,也有公钥算法,分组算法,和操作模式的OID.它们是一种高效且可移植的表示数据包中所选算法的形式.

     对OID的编码规则:

∙ 

o前两部分如果定义为x.y,那么它们将合成一个字40*x+y,其余部分单独作为一个字节进行编码.

o每个字首先被分割为最少数量的没有头零数字的7位数字.这些数字以big-endian格式进行组织,并且一个接一个地组合成字节.除了编码的最后一个字节外,其他所有字节的最高位(位8)都为1.

    举例:

30331=1*128^2+108*128+123 分割成7位数字(0x80)后为{1,108,123}设置最高位后变成{129,236,123}.如果该字只有一个7位数字,那么最高为0.

 

    MD5OID的编码:

       1.将1.2.840.113549.2.5转换成字数组{42,840,113549,2,5}.

       2.然后将每个字分割为带有最高位的7位数字,{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}.

       3.最后完整的编码为0x06082A864886F70D0205. 

 

3.9ASN.1序列和集合类型

 序列(SEQUENCE)和单一序列(SEQUENCEOF)以及相应的集合(SET)和单一集合(SETOF)类型叫做"结构"类型或简单容器.它们是一种用来把相关数据元素收集为一个独立的可解码元素的简单方法.

     序列编码有以下性质:

     1.编码是结构化的.即头字节的位6必须设置. 

 2.编码的内容是由ASN.1序列类型定义列表中的所有数据类型值的完全编码所组成,并且按照它们出现的顺序进行编码,除非这些类型被可选(OPTIONAL)或默认(DEFAULT)关键字所引用.

 例:

考虑如下序列

 User:

:

==SEQUENCE{

         ID       INTEGER,

         ActiveBOOLEAN

     }

    当取值为{32,TRUE}时,编码为0x30060201200101FF}在ASN.1文档里,使用空格来表示编码的属性.

 0x3006

              020120

              0101FF

 

3.10ASN.1可打印字符串和IA5String类型

       可打印字符串(PrintableString)和IA5String类型定义了一种独立于本地代码页和字符集定义,在任何平台上都可以将ASCII字符串编码为可读字符串的可移植方法.

      可打印字符串对象是ASCII集合的一个有限子集,这个子集包括32,39,40~41,43~58,61,63以及65~122.

      IA5String类型的编码对象是ASCII集合中的大多数.包括NULL,BEL,TAB,NL,LF,CR以及32~126.

      可打印字符串和IA5String的编码和八位位组串相似.可打印字符串的头字节是0x13,IA5String的是0x16.例如:

"HelloWorld"的编码为0x130B48656D6D6F20576F726D64.

 

3.11ASN.1世界协调时类型

       世界协调时(UTCTIME)定义了一种相对GMT时间的标准时间(以日期)编码.它使用"YYMMDDHHMMSSZ"的格式分别表示年,月,日,时,分,秒.其中"Z"是遗留自初始的UTCTIME.如果没有

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2