Feb ,2009 발표자 : 조한구 (소프트웨어 연구개발부) ASN.1 & BER Feb ,2009 발표자 : 조한구 (소프트웨어 연구개발부)
What is ASN.1? ASN 이란? ASN 의 중요성 Abstract Syntax Notation : 추상적 데이터 표기법 ASN 의 중요성 국제표준화된 표기법. 제공업체, 플랫폼, 언어에 대한 의존성이 없음 BER, DER 등 ASN 인코딩 방법이 지원됨 ASN 을 특정 개발환경에 맞게 자동변환 시켜주는 컴파일러가 지원됨 (ASN.1 Compiler) TCP/IP 가 인터넷상에서 표준 역할을 하듯이 ASN 은 많은 어플리케이션 간의 통신 프로토콜에서 참조한다.
ASN.1 표기를 사용하는 문서 (PKI) RFC 2459, 3280 : 인증서의 데이터 구성형식 RFC 2251-2256 : LDAP (Lightweight Directory Access Protocol) PKCS : Public Key Cryptography Standard 공개키 암호표준 CMP, CRMP : Certificate Management Protocol 인증서 발급프로토콜 ... 참고 : 관련 국제기관 ITU-T : International Telecommunications Union Telecommunications Standards Sector 국제전신전화 자문위원회. UN의 통신 전문 산하기관 ISO : International Standards Organization 국제표준기구 IETF : Internet Engineering Task Force 인터넷 표준안을 제정하기 위한 기술위원회이며, RFC의 실제 출판을 담당한다. IEEE(Institute of Electrical and Electronics Engineers. Inc) 1884년 전기 및 전자 분야의 기술자들을 훈련시키기위해 설립된 단체로 전기, 전자, 컴퓨터, 전산 분야 등의 기술 분야에 대한 표준 제정, 세미나 및 회의 개최, 교육 등 다양한 활동을 하고 있다.
ASN 표기의 인코딩 방법 BER : Basic Encoding Rules – which allows options for the encoder. DER : Distinguished Encoding Rules - which resolves all options in a particular direction. CER : Canonical Encoding Rules – which resolves all options in the other direction. PER : Packed Encoding Rules. 미래지향적 인코딩. 데이터의 사이즈를 효율적으로... XER : XML Encoding Rules DER 형식을 많이 쓰는 이유 : BER 의 잘 다듬어진 인코딩이다 ( It is arguably the case that CER is technically superior, but there is no doubt that DER has become the de facto distinguished/canonical encoding for BER ) BER, DER, CER 의 차이는 사소하므로 대부분의 인코딩 툴은 세가지 모두 지원한다.
ASN 의 DER 인코딩 예 ASN.1 표기 : PKCS#1 v2.1 출저 DER 인코딩 (Hex) RSAPrivateKey ::= SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent12 INTEGER, -- d mod (q-1) coefficient INTEGER, -- (inverse of q) mod p otherPrimeInfos OtherPrimeInfos OPTIONAL } DER 인코딩 (Hex) 30 82 04 A5 02 01 00 02 82 01 01 00 AA 7A 30 E2 59 68 D4 3A 1E 13 79 6D 05 D7 8C FF 92 88 76 62 D7 72 50 DE A5 10 54 F4 27 66 77 0F DB 38 5A 4B FC 09 3D 20 6B BD 72 68 62 92 0F 61 B0 48 FC 46 F3 08 78 3E 3E 74 22 1A 23 44 74 79 30 B8 A0 A8 D0 76 77 B0 0D A8 82 61 85 A0 59 EE E6 CA 35 08 ... ViewBER 툴로 조회한 모습 각 필드의 값 정하기 version = 0; modulus = AA 7A 30 E2 59 68 ... publicExponent = 65537 = 01 00 01 privateExponent = 8D 63 E8 B5 62 B8 6A 04 85 BB ... prime1 = E3 4B 78 D7 3A B2 FD F7 94 FB 20 ... ...
All possible values of this top-level type 추상적 표기의 구체화 과정 From abstract specification to bits-on-the-line A top-level type definition, supported by other type and value definitions. ASN.1 specification name ::= OCTET STRING age ::= INTEGER All possible values of this top-level type name = “pluto” age = 3 Values The Abstract Syntax MyDog ::= SEQUENCE { name UTF8String, age INTEGER } Abstract values Apply a specific ASN.1 Encoding Rule specification ASN.1 Encoding Rules 30 0A 0C 05 70 6C 75 74 6F 02 01 03 Transfer Syntaxes Bit patterens 00110000 00000110 00000110 000000 0011000000000110...
BER (The Basic Encoding Rules) BER : ASN.1 의 대표적인 인코딩 규칙. BER 로 정의되는 모든 데이터는 TLV (Tag part + Length part + Value part) 형태로 이루어진다. T (Tag) : 사전 정의된 기본데이터 타입. 시간, 문자열, 숫자등의 표기가 정의 되어 있으며 어플리케이션에서 정의한 다른 타입들은 기본데이터 타입으로 나타내어질 수 있다. L (Length) : Value 의 길이. BER 의 특정 규칙을 따른다. V (Value) : 실제 표현하고자 하는 값. Tag 에 따라 표현되는 규칙이 정해진다.
BER : Tag TLV 형태에서 가장 먼저 나오는 데이터 타입 대부분 1 바이트(Octet) 로 표기됨 T L V 8 7 6 Assignment of UNIVERSAL class tags (ASN.1) UNIVERSAL 0 Reserved for use by the encoding rules UNIVERSAL 1 Boolean type UNIVERSAL 2 Integer type UNIVERSAL 3 Bitstring type UNIVERSAL 4 Octetstring type UNIVERSAL 5 Null type UNIVERSAL 6 Object identifier type UNIVERSAL 7 Object descriptor type UNIVERSAL 8 External type and Instance-of type UNIVERSAL 9 Real type UNIVERSAL 10 Enumerated type UNIVERSAL 11 Embedded-pdv type UNIVERSAL 12 UTF8String type UNIVERSAL 13-15 Reserved for future editions of this Recommendation | International Standard UNIVERSAL 16 Suquence and Sequence-of types UNIVERSAL 17 Set and Set-of types UNIVERSAL 18-22 Character string types UNIVERSAL 23-24 Time types UNIVERSAL 25-30 More character string types UNIVERSAL 31-... Reserved for addenda to this Recommendation | International Standard Tag 구성 (1 octet) : Class + P/C + Number Class Bit 8 Bit 7 Universal Application 1 Context-specific Private 0 ~ 30 숫자 (31 은 escape marker) 8 7 6 5 4 3 2 1 Class P/C Number 1 (constructed) : if the V part of the encoding is itself a series of TLV encodings. (SEQUENCE, SET...) 0 (primitive) : otherwise
BER : Tag 의 예 SEQUENCE 00110000 = 0x30 INTEGER 00000010 = 0x02 T L V 이것만은 알아두자 많이 쓰이는 Tag 목록 SEQUENCE 이름 값 (0x) 의미 BOOLEAN 01 Boolean 형의 데이터 INTEGER 02 정수 데이터 BITSTRING 03 비트 스트링 OCTETSTRING 04 8비트 단위 스트링 NULL 05 값 없음 OBJECTIDENTIFIER 06 오브젝트 아이디 PRINTABLESTRING 13 문자 IA5STRING 16 UTCTIME 17 시간 GENERALIZEDTIME 18 UTF8STRING 0C SEQUENCE 30 데이터 조합 SET 31 CONTEXTSPECIFIC A0 Class =Universal P/C = Constructed Number = UNIVERSAL 16 1 00110000 = 0x30 INTEGER Class =Universal P/C = Primitive Number = UNIVERSAL 02 1 00000010 = 0x02
The indefinite form 은 잘 안 쓰이므로 내용 생략합니다. BER : Length T L V 가장 중요한 필드로서 인코딩 방법을 정확이 알아야 함 Length part 는 The short form, The long form, The indefinite form 등 세 가지 form 을 가진다. The short form : V part 의 바이트 길이가 0 이상 127 이하일 때. Length part 는 1 바이트를 차지한다. Left most bit (bit 8) 은 0 이다 길이 값은 most significant bit 를 가진다 The Long form : bit 8 이 1 로 세팅될 때. 나머지 7 bit 에는 Length of Length (=N)값을 넣는다. 이어서 N 바이트 만큼 Length 를 표기한다. 길이 값은 most significant bit 를 가진다 Bit 8 7 6 5 4 3 2 1 Value Length V part 길이가 4 이면 Length 는 00000100 을 가진다 Bit 8 7 6 5 4 3 2 1 Value Length of Length (N) V part 길이가 256 이면 Length of Length 는 10000002 = 0x82 Bit 8 7 6 5 4 3 2 1 Value First octet (1) of Length First octet 은 00000001 = 0x01 참고 : most significant bit 란? 비트 수가 클수록 왼쪽에 배치함을 의미한다. 위 표처럼 1 바이트를 비트로 나타내는 경우 8 번째 비트를 가장 왼쪽에 세팅한다. 예를 들어 정수 1을 8비트의 most significant bit 로 나타내면 00000001 이다. 이와 반대로 least significant bit 로 나타내면 10000000 이 될 것이다. 이와 같은 배열순서의 형식은 바이트 배열에서도 찾아볼 수 있다. 4 바이트 int 값에서 상위바이트를 왼쪽에 배치하는 방식을 Big Endian 이라 하며, 그와 반대를 Little Endian 이라 한다. 또한 네트워크 상에서 데이터를 전송할 때 특별히 Network byte order 라고 하며 Big Endian 과 같은 형식이라 할 수 있다. Second octet 은 00000000 = 0x00 ... Bit 8 7 6 5 4 3 2 1 Value Last octet (N) of Length The indefinite form 은 잘 안 쓰이므로 내용 생략합니다.
BER : Length 인코딩 예 T L V V part 의 길이 Length (Bit 표현) Length (Hexa 표현) 이것만은 알아두자 V part 의 길이 Length (Bit 표현) Length (Hexa 표현) 비고 1 00000001 0x01 The short form 127 01111111 0x7F 128 10000001 10000000 0x81 0x80 The long form 255 10000001 11111111 0x81 0xff 256 10000002 00000001 00000000 0x82 0x01 0x00 65537 10000003 00000001 00000000 00000001 0x83 0x01 0x00 0x01 참고 V part 의 길이가 127 보다 작은 경우에도 The long form 으로 나타낼 수 있다. 예를 들어 Vpart 의 길이가 1 일 때 The long form 으로 나타내면 0x81 0x01 또는 0x82 0x00 0x01 ... 이런식으로 나타낼 수 있으나 관례상 데이터의 길이는 가장 적은 바이트 수로 표시한다. 따라서 0x01 로 표현하는 게 적절하다.
BER : Value 의 인코딩 Value (V part) 의 표기는 앞 Tag 에 따라서 형식이 정해진다. 여기서는 그 중 자주 쓰이는 타입만을 언급한다. NULL (0x05) INTEGER (0x02) The value of null NULL ::= NULL (the only value of the NULL type) is encoded as T L V null 05 00 empty The values of integer1 INTEGER ::= 72 integer2 INTEGER ::= 127 integer2 INTEGER ::= -128 integer2 INTEGER ::= 128 are encoded as T L V integer1 02 01 48 integer2 02 01 7F integer3 02 01 80 integer4 02 02 00 80 Value 에 값이 없음을 의미한다. 따라서 이 경우는 항상 05 00 이다. BOOLEAN (0x01) The values of boolean1 BOOLEAN ::= TRUE boolean1 BOOLEAN ::= FALSE are encoded as T L V boolean1 01 01 FF ( TRUE ) boolean2 01 01 00 ( FALSE ) INTEGER 는 음수를 표기할 수 있으므로 표기방법에 유의해야 한다. Value 에서 첫번째 바이트가 0x80 이상이면 음수를 뜻한다. 따라서 첫번째 바이트가 128 이상의 양수임을 표시하려면 0x00 을 먼저 붙여야 한다. 음수 표현은 2 의 보수 (two’s complement) 형태이며, C 에서는 char 타입이 Java 에서는 byte 타입이 이런 형태로 표현된다. BER 에서는 이론적으로 (NULL 타입처럼) L=0 이고 V 는 값이 없도록 표현이 가능하나, INTEGER 의 V 는 최소한 1 바이트 이상이 된다고 보아야 한다. Value 에는 TRUE 또는 FALSE 만이 올 수 있다. 값 TRUE 에 대하여 DER, CER 에서는 V = FF 만이 허용되며, BER 의 경우 00 이 아니기만 하면된다.
BER : Value 의 인코딩 T L V OCTET STRING (0x04) The value of octetstring OCTET STRING ::= “01234” is encoded as T L V octetstromg 04 05 30 31 32 33 34 35 CHOISE (타입없음) value1 CHOICE { flag BOOLEAN, value INTEGER } ::= flag : TRUE value2 CHOICE value INTEGER } ::= value:72 we get the encodings T L V value1 01 01 FF value2 02 01 48 octet (바이트) 단위로 표현될 수 있는 곳에 많이 쓰임 V 의 길이가 길면 fragment 단위로 나누어서 표현할 수 있다. CER 의 경우 fragment = 1000 바이트로 고정시켰다. V 가 문자열을 표시하는 PRINTABLE STRING , IA5 STRING , UTF8 STRING 등도 타입만 다르고 표기방법은 위와 같다 BIT STRING (0x03) The values of bitstring BIT STRING ::= 1111000011110000111101 -> bit 값 are encoded as T L V bitstring 03 03 02FF0F0F4 CHOICE 는 T part 와 L part 없이 V 값으로 표현된다. CHOICE 의 경우 해당 집합 중에 하나만 선택된다. C 언어에서 union 구조체와 흡사함. bit 값을 표현할 때 쓰임. V part 첫 번째 바이트는 사용하지 않은 비트를 표시 (대부분 00) 그 외에는 OCTET STRING 과 동일. unused bit
BER : Value 의 인코딩 T L V SEQUENCE (OF) (0x30) SET (OF) (0x31) The value of temperature SEQUENCE (7) OF INTEGER ::= {21, 15, 5, -2, 5, 10, 5} could be encoded as T L V temperature 30 08 T L V 02 01 15 02 01 0F 02 01 05 02 01 FE 02 01 10 The value of temperature SEQUENCE (7) OF INTEGER ::= {21, 15, 5, -2, 5, 10, 5} could be encoded as T L V temperature 30 80 T L V 02 01 FE 02 01 15 02 01 10 02 01 0F 02 01 05 SEQUENCE 와 SET 타입은 가장 많이 쓰임 SEQUENCE 는 다른 데이터의 집합이다. SEQUENCE 의 V part 에는 다른 TLV 들이 열거된다. V 의 값들은 정의된 순서대로 인코딩 되어져야 한다. SET 은 타입이 0x31 이라는 것을 제외하면 SEQUENCE 와 동일한다. 그러나 CER / DER 로 인코딩 되어질 때는 V 의 값들은 ascending order 를 따른다. 이때 V 값은 unsigned hex 값을 기준으로 순서를 매긴다. 따라서 0xFE (-2) 가 0x15 (21) 보다 먼저 나오게 된다. V 값은 INGERGER 타입이 아니더라도 이러한 기준을 따른다. (CER / DER) 이 기준에 의하면 일반적인 스트링값의 나열은 lexical (사전적) order 가 성립한다.
BER : Value 의 인코딩 T L V OBJECT IDENTIFIER (0x06) 기타 (Tagging) The values of oid OBJECT IDENTIFER ::= { 1 0 8571 2 } would be (in hex) T L V oid 06 05 01 00 C27B 02 However the actual encoding of this object identifier value is oid 06 04 28 C27B 02 Howcome? 그 외에 타입이 없는 ASN 표기들은 다음과 같다. OPTIONAL 선택적 표기. OPTIONAL 로 표기된 데이터는 상황에 따라 표기될 수도 있 고 그렇지 않을수도 있다. ANY (DEFINED) 타입이나 값들이 임의로 설정될 수 있는 경우이다. 이 경우 타입 값들은 게체의 성격에 따라 별도로 정의되어 진다. IMPLICIT Tag 에 이 단어가 붙어 있으면 Tag 가 바뀌어니다. (CONTEXT SPECIFIC 형태로... ) EXPLICIT Tag 에 이 단어가 붙으면 TLV 를 CONTEXT SPECIFIC 으로 다시 감싸게 된다. Tagging 의 예 : ContentInfo ::= SEQUENCE { contentType ContentType, content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } PrivateKeyInfo ::= SEQUENCE { version Version, privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, privateKey PrivateKey, attributes [0] IMPLICIT Attributes OPTIONAL } Version ::= INTEGER PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier PrivateKey ::= OCTET STRING Attributes ::= SET OF Attribute ASN 에서 정의된 OID 값을 인코딩 할 때는 V 값의 최적화를 위하여 다소 복잡한 방법을 쓰며 여기서는 생략함 (OID Tree 개념이 필요함) oid 의 값은 개체별로 정해져 있으므로 실전에서 OID 를 인코딩 할 때는 이미 인코딩 되어 있는 값을 가져다 쓰면된다. OID 는 기본적으로 정수값(INTEGER) 의 연속이며 이를 가장 압축적으로 표현하기 위해 SEQUENCE OF INTEGER 인코딩 방법을 사용한다.
예제