7 min read

ASN.1에 대하여

ASN.1에 대하여
Photo by Viktor Forgacs / Unsplash
💡
아래의 Elixir 예제를 github에 올렸으니 참고하시기 바랍니다. https://github.com/devage/asn1-sample

asn.1이란

ASN.1(Abstract Syntax Notation One)은 데이터 구조를 기술하고 표현하는 데 사용하기 위해 ITU-T에서 만든 국제 표준이다. 다양한 분야에서 사용 중이며 특히 X.509 인증서, SNMP 및 S1AP/NGAP 등 통신 프로토콜과 보안 분야에 널리 사용되고 있다.

주요 특징은 다음과 같다.

  1. 언어 중립: 구현 언어에 독립적으로 데이터 구조를 설명하는데 필요한 표현 방법을 제공한다.
  2. 효율성: 목적에 맞게 데이터를 효율적으로 인코딩할 수 있는 여러 방법을 제공한다. 인코딩 규칙(encoding rule)으로 정의하는데 BER(Basic Encoding Rules), DER(Distinguished Encoding Rules), PER(Packed Encoding Rules) 등의 기본 규칙 외에 XML로 인코딩하는 XER, JSON으로 인코딩하는 JER 등이 있다.
  3. 확장성: ASN.1은 기존 구조에 새로운 데이터 형식 및 요소를 추가하여 확장할 수 있는 방법을 제공한다.

asn.1 인코딩과 디코딩을 처리하는 Elixir 코드 작성하기

.asn 파일에 명시된 대로 인코딩 및 디코딩을 처리하는 기능은 Erlang/OTP의 ASN.1 컴파일러를 사용하여 erlang 언어로 자동 생성한다. elixir와 erlang은 모두 같은 BEAM 가상 머신에서 실행되며 elixir에서 erlang 모듈을 바로 호출하여 사용할 수 있기 때문에 같이 사용할 수 있다.

먼저 다음과 같이 ASN.1 내용을 정의하고 MyModule.asn 파일로 저장한다. MySequence는 정수형 id와 utf8 문자열 name로 구성된 자료구조이다.

MyModule DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
  MySequence ::= SEQUENCE {
    id        INTEGER,
    name      UTF8String
  }
END

그 후 Erlang ASN.1 컴파일러를 사용하여 ASN.1 문서를 컴파일한다.

erlc -bper Mymodule.asn

-bper은 PER 인코딩 규칙으로 코드를 생성하기 위한 옵션인데, -bber로 해도 무관하다. 컴파일이 끝나면 MyModule.asn1db, MyModule.hrl, MyModule.erl, MyModule.beam 파일이 생성된다.

이제 mix로 프로젝트를 만들고 위의 MyModule.hrl, MyModule.erl 파일을 복사한다.

mix new asn1_example
mkdir asn1_example/src
cp MyModule.hrl MyModule.erl asn1_example/src/
defmodule Asn1Example do
  require :MyModule

  def encode_my_sequence(id, name) do
    my_sequence = {:MySequence, id,  name}

    case :MyModule.encode(:MySequence, my_sequence) do
      {:ok, encoded_data} -> IO.inspect(:binary.bin_to_list(encoded_data))
      {:error, reason} -> IO.puts(reason)
    end
  end
end

위의 코드에서 :MyModule.encode/2 함수를 호출하여 PER로 인코딩한다. 인코딩 결과를 Elixir 바이너리 형식으로 변환하기 위해 :binary.bin_to_list/1 함수를 사용했다.

이제 실행해볼 차례다.

$ mix compile
$ iex -S mix

iex> elixir prompt가 나오면 다음과 같이 실행한다.

iex> Asn1Example.encode_my_sequence(1, "John Doe")
[1, 1, 8, 74, 111, 104, 110, 32, 68, 111, 101]

BER 인코딩

Basic Encoding Rules (BER)는 ASN.1 기반의 기본 인코딩 방식에 해당한다. BER 인코딩의 주요 특징은 다음과 같다.

  1. TLV 구조: BER 인코딩에서 각 필드는 태그(Tag), 길이(Length), 값(Value)의 세 부분으로 구성되는 TLV 구조를 사용하여 인코딩한다. 태그는 해당 필드의 데이터 타입을 식별하는데 사용되며, 길이는 값 부분의 바이트 크기를 나타냅니다. 값은 실제 데이터를 포함합니다.
  2. 명시적 태그: BER 인코딩에서는 명시적 태그를 사용하여 필드를 구분하고 식별하기 때문에 디코더가 인코딩된 데이터 내에서 필드의 위치와 의미를 쉽게 식별할 수 있다. 그러나 반대급부로 인코딩의 크기가 증가하게 된다.
  3. 가변 길이 인코딩: BER 인코딩은 필드의 길이에 따라 바이트 단위로 가변 길이 인코딩을 사용한다. 작은 값은 적은 수의 바이트로, 큰 값은 더 많은 수의 바이트로 인코딩된다.
  4. 구조적 인코딩: BER 인코딩은 구조체, 배열, 선택적 필드 등으로 구성된 복잡한 계층 구조를 지원한다. 이러한 구조를 효율적으로 표현하기 위해 중첩된 TLV 구조를 사용한다.

BER 인코딩의 단점 중 하나는 실제 전송하려는 데이터에 비해 인코딩된 결과의 크기가 크다는 것이다. 명시적 태그와 가변 길이 인코딩이 한 몫 하는데, 이러한 단점을 해결하기 위해 DER (Distinguished Encoding Rules)와 PER (Packed Encoding Rules)와 같은 다른 인코딩 규칙들을 도입했다.

DER 인코딩

Distinguished Encoding Rules (DER)는 BER을 엄격한 형태로 변형한 것으로, 인코딩의 크기와 복잡성을 줄이고 인코딩의 고유성을 보장하기 위해 다음과 같은 몇 가지 제약 조건을 추가했다.

  1. 최소 길이 인코딩: DER 인코딩에서는 모든 데이터 타입에 대해 최소 길이 인코딩을 사용하며, 가변 길이 필드에 대해 가장 짧은 표현을 사용하도록 한다.
  2. 고유한 인코딩: DER 인코딩에서는 각 ASN.1 데이터 구조에 대해 단일 인코딩만 허용하기 때문에 DER 인코딩된 데이터를 비교하거나 해시하는 것이 용이해진다.
  3. 선택적 필드 최적화: DER 인코딩에서는 선택적 필드가 누락된 경우 해당 필드를 생략하여 인코딩의 크기를 최소화한다.

이러한 추가 제약 조건 덕분에 DER 인코딩은 디지털 서명 및 인증서와 같은 암호화 응용 프로그램처럼 고유성과 인코딩 크기가 중요한 곳에서 유용하게 사용된다. 그러나 이러한 제약 조건이 필요하지 않은 경우에는 BER 인코딩 쪽이 구조적으로 복잡한 데이터를 표현하는데 더 적합할 수 있다.

PER 인코딩

Packed Encoding Rules (PER)는 비트 수준의 인코딩으로, 최소한의 오버헤드를 갖도록 설계되어 네트워크 대역폭 및 저장 공간을 절약하기 위한 인코딩 방식이다. PER은 통신 프로토콜 및 제한된 리소스를 가진 임베디드 시스템에서 사용한다.

PER에는 Aligned PER과 Unaligned PER 두 가지 변형이 있다. APER은 바이트 경계에 정렬된 데이터 인코딩을 사용하고, UPER은 정렬을 하지 않는다. UPER이 더 공간 효율적이지만 처리 시간과 복잡성이 더 높을 수 있다.

PER 인코딩의 몇 가지 주요 특징은 다음과 같다.

  1. 길이 정보 최소화: 고정 길이 필드에 대해서는 길이 정보를 전송하지 않는다. 가변 길이 필드의 경우 최소한의 길이 정보만 전송한다.
  2. 값 간소화: 최소한의 비트만 사용하여 값에 대한 정보를 인코딩한다.
  3. 기본값 생략: 기본값을 가진 필드는, 기본값과 일치하는 경우 인코딩에서 생략한다.
  4. 선택 사항 및 확장: 선택적 필드와 확장 가능한 구조를 처리할 수 있으며, 존재하는 필드와 추가된 필드의 정보를 최소한의 비트로 인코딩한다.
  5. 태그 최소화: 암시적 태그만 필요한 경우에 한해서 사용한다.

따라서 낮은 대역폭의 통신 채널 및 제한된 저장 공간이 있는 임베디드 시스템에서 사용하기에 적합하다.

Reference

erlang의 asn.1 관련한 자세한 내용은 아래 링크를 참고한다.

— END OF POST.