ASN.1 이란 이 기종 컴퓨터 사이에서 메시지 교환 시 사용되는 표기법이다. ASN.1 에는, BER (Bagic Encoding Rule), CER (Canonical Encoding Rule), DER (Distinguished Encoding Rule), PER (Packed Encoding Rule), LWER (Light Weight Encoding Rule), BACnetER (BACnet Encoding Rule), OER (Octet Encoding Rule), SER (Signalling specifc Encoding Rule), XER (XML Encoding Rule) 등 9개의 Encoding rule이 존재 한다.
BER (Bagic Encoding Rules)
- 기본 형태
Tag | Length | Value |
Identifier Octet | Length Octet | Content Octet |
BER 은 4가지 종류의 octets 부분들을 가지고 있다. 첫째로는 Identifier octets, Length octets, Contents octets, 그리고 Indefinite-length 일 때만 나타나는 End-Of-Contents (EOC) octets 부분들이 있다. Contents Octets 는 Constructed Type 인 경우에 그 안에 다시 Tag Octet, Length Octet, Content Octet 을 가질 수 있다.
l Definite – Length
Identifier | Length | Contents |
l Indefinite - Length
Identifier | Length | Contents | EOC ( 2 Octet : 00 00 16 ) |
* Identifier octets
- Low-tag-number form ; Tag Number 가 0 ~ 30 인 경우 하나의 Octet 을 갖는다.
8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
Class | P/C | Tag Number |
Class | : Tag 의 종류로 보통 Universal 을 많이 사용한다. < 표 1 참고> |
P/C | : 이 Data Type 이 Primitive Type 인지 Constructed Type 인지 나타낸다. Primitive Type : 0 Constructed Type : 1 |
Tag Number | : V Type 을 나타낸다. |
Bit 8 | Bit 7 | Class Type | 설명 |
0 | 0 | Universal | X.208 에 정의되어 모든 application 에서 동일하게 사용 |
0 | 1 | Application | X.500 directory service 처럼 한 App 에서만 사용 |
1 | 0 | Context-specific | 주어진 구조적 타입에서 사용하여 동일한 Tag 를 분별 |
1 | 1 | Private | 주어진 회사에서만 사용 |
< 표 1 Class Type >
- High-tag-number form ; Tag Number 가 31 이상인 경우 둘 이상의 Octet 을 갖는다.
8 | 7 | 6 | 5 4 3 2 1 | … | ||||
Class | P/C | 1 1 1 1 1 | 1 | X X X X X X X | 0 | X X X X X X X | ||
첫번째 Octet 의 Tag Number 부분을 1로 채우고, 마지막 Octet 을 제외한 모든 Octet 의 Bit 8 는 1로 Setting 한다.
Tag Number 를 알고자 할 때는 두 번째 Octet 부터 마지막 Octet까지 Bit 1에서 Bit 7 까지만 가지고 계산한다.
예) 00 1 11111 1 0000001 0 0000011 => Tag Number 는 00000010000011 = 131 이다.
* Length Octet
; Contents Octet 의 길이를 나타낸다.
- Short form ; length 가 0 ~ 127 인 경우
8 | 7 6 5 4 3 2 1 |
0 | Length |
- Long form ; length 가 0 ~ 2 1008 –1 (256126 –1 ) 인 경우
8 | 7 6 5 4 3 2 1 | 8 7 6 5 4 3 2 1 | … | 8 7 6 5 4 3 2 1 |
1 | Length Octet의 길이 | Length1 | Lengthn |
|ç==== 실제 contents 의 길이 ====è|
- Indefinite length 인 경우
8 | 7 6 5 4 3 2 1 | Content Octet | EOC | |
1 | 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 |
* Content Octet
주어진 Value 를 표현하는 것.
< Class : Universal , Length 는 Short-form 을 기본으로 작성>
# Boolean
- False ; Value 가 0
Tag = 1 | Length = 1 | Value = 0 |
0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
< HEX 표시 >
è 01 01 00
- True ; Value 가 0 이 아닌 어떤 수 (0 만 아니면 모두 가능)
0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 |
OR | ||
0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 | 1 1 1 1 1 1 1 1 |
è 01 01 01
è 01 01 FF
= Integer
- Positive
Tag = 2 | Length = 2 | V = 1122 | |
0 0 0 0 0 0 0 10 | 0 0 0 0 0 0 1 0 | 0 0 0 0 0 1 0 0 | 0 1 1 0 0 0 1 0 |
è 02 02 04 62
Positive Integer 의 경우 Value 의 가장 왼쪽 Bit가 1 로 Setting 되어 있으면 음수와 혼동할 수가 있으므로 부호 확인을 위해서 가장 왼쪽 Bit 를 0 으로 만들기 위해 Value 의 맨 앞에 0016 을 더한다.
예) 128 의 Value -> 1000 0000 : 부호 확인을 위해 0016 + => 0000 0000 1000 0000
- Negative ( 2’s-complement )
T = 2 | L = 1 | V = -128 |
0 0 0 0 0 0 1 0 | 0 0 0 0 0 0 0 1 | 1 0 0 0 0 0 0 0 |
è 02 01 80
Negative Integer 의 경우 Value 의 가장 왼쪽 Bit 가 1로 Setting 되어 있으면 이는 음수임을 나타내므로 부호 확인을 위해 더하는 Octet 이 필요 없다. 만약 Value 의 가장 왼쪽 Bit 가 0 으로 Setting 되어 있으면 양수와 혼동할 수가 있으므로 Value 의 맨 앞에 FF16 을 더한다.
예) –129 의 Value(2’s-complement) -> 0111 1111 : 부호 확인을 위해 FF16 +
=> 1111 1111 0111 1111
Integer | BER | Integer | BER |
0 | 02 01 00 | 256 | 02 02 01 00 |
127 | 02 01 7F | -127 | 02 01 81 |
128 | 02 01 00 80 | -128 | 02 01 80 |
129 | 02 01 00 81 | -129 | 02 02 FF 7F |
< Integer Value 의 BER >
; Value 의 맨 앞에서부터 9 개의 Bit 는 동일하게 0 또는 1 로 Setting 되지 않는다.
-> 최소의 Size 유지 가능
= Enumerated
; 여러 개의 Integer 값 중에서 하나만을 선택하는 것이기 때문에 Tag 가 10 인 것을 제외하면 Integer 와 동일하다.
= Bit String
; 임의의 Bit 의 연속적인 String 으로 Value 의 첫번째 Octet 에는 Unused bit의 수를 check 해서 덧붙여 준다.
T = 3 | L = 3 | unused Bit = 3 | V = 1011011101011 | |
00000011 | 00000011 | 0 0 0 0 0 0 1 1 | 1 0 1 1 0 1 1 1 | 0 1 0 1 1 X X X |
è ( X = 0 인 경우 ) 03 03 03 B7 58
Unused Bit 는 Bit String 을 앞에서부터 차례대로 다 채운 뒤 마지막 Octet 의 나머지 부분을 채우기 위해 넣은 Value 가 아닌 0 이나 1 또는 둘을 섞어서 넣은 부분( X ) 의 개수를 말한다. 거의 0으로 채우는 경우가 많다.
Value 부분에는 Constructed 한 Bit String 이 들어갈 수 있다.
예) ‘ 10011011101011 ‘ 을 8 Bit 씩 나눠서 구성할 때
00100011 00001000 è 23 08
00000011 00000010 00000000 10110111 è 03 02 00 B7
00000011 00000010 00000011 01011000 è 03 02 03 58
= Octet String
; eight-bit values 인 octets의 String 을 나타낸다. Bit String 과 유사하나 Unused Bit 를 check 하지 않는다.
T = 4 | L = 08 | V = ( 01 23 45 67 89 AB CD EF ) 16 |
00000100 | 00001000 | ( 01 23 45 67 89 AB CD EF ) 16 |
è 04 08 01 23 45 67 89 AB CD EF
; Value 부분에 Constructed 한 Octet String 을 가질 수 있다.
= Null
; Null 을 나타내는 것으로 Content Octet 이 존재하지 않으므로 Constructed 구성을 할 수가 없다. (거의 불변이라 할 수 있다. )
T = 5 | L = 0 |
00000101 | 00000000 |
è 05 00
è Long –form 인 경우 : 05 81 00
= Object Identifier
; 주어진 Object Identifier value 로 Object Identifier 를 나타낸다.
T = 6 | L = 7 | V = 1 2 840 113549 1 |
00000110 | 00000110 | ( 2A 86 48 86 F7 0D 01 ) 16 |
=> 06 07 2A 86 48 86 F7 0D 01
Value 의 첫번째는 Value1 * 40 + Value 2 이다.
: Value1 은 0 , 1 , 2 만을 가질 수 있다.
: Value2 는 Value1 이 0 이나 1 일 때 0 ~ 39 의 수를 갖는다.
X.208에서는 적어도 2 이상을 갖는다.
두 번째 Octet 부터는 하나의 Value 를 계산할 때마다 128 Base 로 하고 하나의 Value 가 두개 이상의 Octet 을 필요로 할 때는 High-tag-number form 처럼 마지막 Octet 을 제외하고 모든 Octet 의 Bit 8 은 1로 Setting 된다.
128 Base 는 한 Octet 에서 사용하는 비트의 수가 7 개이기 때문이다. ( 27 = 128 )
예) 1 2 840 113549 1
1 * 40 + 2 = 42 => 2A 16 è 0010 1010
840 = 6 * 128 + 72 =>( 06 48 ) 16 è 1000 0110 0100 1000 => 86 48
113549 = 6 * 1282 + 119 * 128 + 13 =>( 06 77 0D ) 16
è 1000 0110 1111 0111 0000 1101 => 86 F7 0D
1 = 1 => 01 16 è 0000 0001 => 01
========è 2A 86 48 86 F7 0D 01
= Real
= Sequence (of)
; Sequence 는 다른 Type 의 Value 들을 한가지 이상 순서적으로 가질 수 있는 Constructed Type 이고, Sequence Of 는 동일한 Type 의 Value 들을 0 개 또는 여러 개 순서적으로 가질 수 있는 Constructed Type 이다. 이를 C 언어와 비교해보면 Sequence 는 struct type 이고, Sequence Of 는 array type 이다. 이 둘은 동일한 Tag Number 를 갖는다.
T = 16 | L = 6 | V | ||
00110000 | 00000110 | T = 2 | L = 1 | V = 10 |
00000010 | 00000001 | 0000000A | ||
T = 1 | L = 1 | V = true | ||
00000001 | 00000001 | 11111111 |
è 30 06
02 01 0A
01 01 FF
< Sequence Type > : Contents 내의 Tag Type 이 다름
T = 16 | L = 6 | V | ||
00110000 | 00000110 | T = 2 | L = 1 | V = 10 |
00000010 | 00000001 | 00001010 | ||
T = 2 | L = 1 | V = 15 | ||
00000010 | 00000001 | 00001111 |
è 30 06
02 01 0A
02 01 FF
< Sequence Of Type > : Contents 내의 Tag Type 이 같음
= Set (Of)
; Set 은 다른 Type 의 Value 들을 한가지 이상 순서 없이 가질 수 있는 Constructed Type 이고 Set Of 는 주어진 동일한 Type 의 Value 들을 0 개 또는 여러 개 순서 없이 가질 수 있는 Constructed Type 이다. 이 둘은 동일한 Tag Number 를 사용한다.
; 현재 Set 은 PKCS 에서 사용되지 않고 있다.
예 ) 만약 A 의 정의가 다음과 같다면 A 는 B 를 0개 이상 순서에 상관없이 가질 수 있다.
A ::= SET OF B
è A = B or BB or BBB ……
= PrintableString
; 다음과 같은 문자들로만 이루어진 String 으로 Constructed 구성이 가능하다.
A, B, ………… Z a, b, ………… z
0, 1, ………… 9 (space) ‘ ( ) + , - . / : = ?
T = 19 | L = 2 | V = “KR” (4B 52 16 ) |
00010011 | 00000010 | 01001011 01010010 |
è 13 02 4B 52
= T61String
; ASCII 를 8 Bit 로 확장한 String (T. 61) 으로 흔히 라틴어나 일본어 등을 표현할 때 사용하는 것으로 프린트 할 수 없는 제어 문자가 들어 있다. Value 에 Constructed 구성이 가능하다. 0을 포함한 어떤 길이도 가능하다.
프랑스어로 “ Public keys ” 를 나타내면.
T = 20 | L = 15 | V = Cle’s publiques => 63 6C C2 65 73 20 70 75 62 6C 69 71 75 65 73 16 |
00010100 | 00001111 | ( 63 6C C2 65 73 20 70 75 62 6C 69 71 75 65 73 )16 |
è 14 0F 63 6C C2 65 73 20 70 75 62 6C 69 71 75 65 73 16
위에서 C2 는 그 다음 글자의 악센트 표시를 의미한다.
= IA5 String
; ASCII 와 비슷한 7 Bit 인 IA5 문자 Set 을 사용할 때 사용된다. 이 IA5 는 ASCII 와 달리 non-printing control character 를 포함하고 있다. 0을 포함한 어떤 길이도 가능하다.
T = 22 | L = 8 | V = a1@d.com => 61 31 40 64 2E |
00010110 | 00001000 | ( 61 31 40 64 2E 63 6F 6D )16 |
è 16 08 61 31 40 64 2E 63 6F 6D
= UTCTime
; 시간을 나타낼 때 사용된다. GMT(Greenwich Mean Time) 이나 GMT 로부터 Local Time 의 offset 을 나타낸다. 다음과 같은 형식을 갖는다.
YYMMDDhhmmZ
YYMMDDhhmm+hh’mm’
YYMMDDhhmm-hh’mm’
YYMMDDhhmmssZ
YYMMDDhhmmss+hh’mm’
YYMMDDhhmmss-hh’mm’
YY | 년도 뒤에서 두자리 ( 00 ~ 99 ) | hh’ | GMT 시간으로부터의 시간 offset |
MM | 월 ( 01~ 12 ) | mm’ | GMT 시간으로부터의 분 offset |
DD | 일 ( 01 ~ 31 ) | Z | 현재 GMT |
hh | 시간 ( 00 ~ 23 ) | + | GMT 보다 늦은 |
mm | 분 ( 00 ~ 59 ) | - | GMT 보다 빠른 |
ss | 초 ( 00 ~ 59 ) |
동일한 시간은 다음과 같이 여러 가지 형태로 나타낼 수 있다.
예) 2000 년 10 월 25 일 오후 4 시 30 분 01 초
YYMMDDhhmmssZ è 001025070001Z
YYMMDDhhmmss+hh’mm’ è 001025163001+0900
T = 23 | L = 13 | V = 001025070001Z => ( 30 30 31 30 32 35 30 37 30 30 30 31 5A ) 16 |
00010111 | 00001101 | ( 30 30 31 30 32 35 30 37 30 30 30 31 5A ) 16 |
è 17 0D 30 30 31 30 32 35 30 37 30 30 30 31 5A
== IMPLICIT Tag Type
; Type 내의 Tag 를 변경함으로써 다른 타입으로부터 얻어진 타입으로 다음과 같은 형식으로 표기된다.
[[class] number] IMPLICIT Type
class 이름 이 지정되지 않은 경우는 기본적으로 context-specific 으로 지정된다.
예 ) A [1] IMPLICIT Integer ::= 3
T = 1 | L = 1 | V = 3 |
10000001 | 00000001 | 00000011 |
위의 Tag 에서 앞의 10 은 context-specific 을 나타내고, 뒤의 00001 은 [ ] 안의 number 를 나타낸다.
예 ) B [APPLICATION 0] IMPLICIT Integer ::= 3
T = 0 | L = 1 | V = 3 |
01000000 | 00000001 | 00000011 |
[ ] 안에 Class 가 Application 으로 지정되어서 앞의 2 Bit 가 01 이 되고 뒤의 00000 은 [ ] 안의 number 를 나타낸다.
Value 로 constructed Type 을 가질 수가 있는데 이 때만 constructed type 이l 된다.
예) C [2] IMPLICIT D
D ::= Sequence { Int 3, Null }
D è 30 05 02 01 03 05 00 16
C è A2 05 02 01 03 05 00
10 1 00010
== EXPLICIT Tag Type
; Type 내의 Tag 를 변경하지 않고 Tag, Length, Value 를 갖고 Value 안에 주어진 Type을 기술함으로써 얻어진 타입으로 다음과 같은 형식으로 표기된다
[[class] number] EXPLICIT Type
예) A [0] EXPLICIT Integer ::= 3
T = 0 | L = 3 | T = 2 | L = 1 | V = 3 |
10100000 | 00000011 | 00000010 | 00000001 | 00000011 |
Class type 이 없으면 IMPLICIT Tag 와 동일하게 context-specific 으로 지정된다.
Tag Octet 의 세 번째 Bit 는 EXPLICIT Tag 가 기본적으로 Value 부분에 또 다른 Type 을 포함하기 때문에 항상 1 이 된다.
= TeletexString
T61String 과 동일하게 T.61 문자 Set 을 사용한다.
= NumericString
; 표현 가능한 문자가 0 – 9 그리고 space 뿐이다. Otect String 준함.
= VideotexString
; T.100, T.101 문자 Set 을 사용하여 String을 표현한다.
= GraphicString
; ISO8824 문자 Set 을 사용하여 String 을 표현한다.
= VisibleString
; ASCII 라 불리기도 하는 ISO 646 문자 Set 을 사용한다.
= GeneralString
;
* CHOICE, ANY
; 실제 Encoding Rule 에는 존재하지 않는다. 그러나 내부적으로 선택된 Data Type 의 Encoding 으로 CHOICE, ANY 의 형태를 구현하는 것이다.