Programming/Python

[Python] ASN.1(Abstract Syntax Notation One) for 3GPP

Lowell Ahn 2026. 5. 11. 01:27
Python · ASN.1 · 3GPP Protocol

[Python] ASN.1(Abstract Syntax Notation One) for 3GPP

3GPP 프로토콜을 분석하다 보면 RRC, NGAP, F1AP, E1AP 같은 메시지 정의에서 ASN.1을 자주 만나게 됩니다. 이번 글에서는 ASN.1이 무엇인지, 왜 3GPP에서 중요한지, 그리고 Python으로 학습용 메시지를 encode/decode하는 흐름을 실습 중심으로 정리합니다.

  • 대상: 3GPP 프로토콜 입문자
  • 도구: Python + asn1tools
  • 범위: ASN.1 개념, PER, toy schema 실습
Python ASN.1 for 3GPP concept 3GPP 메시지 정의가 ASN.1 스키마를 거쳐 Python encoder와 decoder로 처리되는 흐름 3GPP Spec ASN.1 Schema / Types / Constraints Python encode · decode · inspect Bits on the wire: PER / UPER / APER

그림 1. ASN.1은 스펙 문서의 메시지 정의와 실제 바이트 스트림 사이를 연결하는 “구조 설명 언어”로 이해할 수 있습니다.

이번 글에서 다룰 내용

  1. ASN.1이 필요한 이유
  2. 3GPP에서 ASN.1이 등장하는 위치
  3. Python으로 ASN.1을 다루는 기본 흐름
  4. 학습용 ASN.1 schema 작성
  5. PER/UPER encode & decode 예제
  6. 실제 3GPP 분석 시 주의할 점

1. ASN.1이란?

ASN.1(Abstract Syntax Notation One)은 데이터를 어떤 구조로 표현할지 정의하는 표기법입니다. 쉽게 말하면 “이 메시지는 어떤 필드를 가지고, 각 필드는 어떤 타입이며, 값의 범위는 어디까지인가”를 문서화하는 언어입니다.

JSON이나 XML은 사람이 읽기 좋은 데이터 표현에 가깝지만, 이동통신 프로토콜에서는 대역폭과 처리 효율이 중요합니다. 그래서 3GPP 프로토콜에서는 메시지 구조를 ASN.1로 정의하고, 실제 전송 시에는 PER 같은 이진 encoding rule을 적용하는 경우가 많습니다.

처음 ASN.1을 접했을 때 가장 헷갈렸던 부분은 “문법 자체”보다도 이 정의가 실제 무선 메시지의 bit stream과 어떻게 연결되는지였습니다. 그래서 ASN.1은 문서 문법으로만 보지 말고, encode/decode의 기준표로 보는 편이 이해하기 쉽습니다.

핵심 한 줄: ASN.1은 “메시지 구조를 정의하는 언어”이고, PER/UPER/APER는 “그 구조를 실제 bit stream으로 바꾸는 규칙”입니다.

2. 3GPP에서 ASN.1이 중요한 이유

3GPP 시스템에서는 UE, gNB, AMF, CU, DU 같은 여러 네트워크 노드가 정해진 메시지 형식으로 통신합니다. 이때 메시지 필드의 순서, 선택 여부, 확장 가능성, 값 범위가 서로 다르게 해석되면 상호운용성이 깨집니다.

ASN.1은 이런 문제를 줄이기 위해 프로토콜 메시지를 엄격한 타입 시스템으로 정의합니다. 예를 들어 어떤 필드는 정수이고, 어떤 필드는 선택 사항이며, 어떤 필드는 여러 후보 중 하나만 선택되는 구조라는 것을 명확하게 표현할 수 있습니다.

실제 로그를 볼 때는 메시지 이름만으로는 충분하지 않습니다. 같은 메시지처럼 보여도 내부 IE 구성이나 extension field 여부에 따라 해석이 달라질 수 있기 때문에, 결국 ASN.1 정의를 따라가며 필드 구조를 확인하게 됩니다.

RRC

UE와 gNB 사이의 무선 자원 제어 메시지를 이해할 때 ASN.1 구조를 자주 확인합니다.

NGAP

gNB와 AMF 사이의 제어 평면 메시지를 분석할 때 ASN.1 기반 구조가 중요합니다.

F1AP / E1AP

CU-DU, CU-CP/CU-UP 분리 구조를 공부할 때 메시지 정의와 IE 구성이 핵심입니다.

XnAP

gNB 간 연결, 이동성, 이웃 노드 간 절차를 볼 때 ASN.1 메시지를 만나게 됩니다.

3. ASN.1을 읽을 때 보는 기본 문법

처음 ASN.1을 보면 괄호, 대문자 타입, OPTIONAL, CHOICE, SEQUENCE 때문에 어렵게 느껴질 수 있습니다. 하지만 3GPP 메시지 분석 관점에서는 먼저 아래 네 가지를 잡으면 됩니다.

문법 의미 분석 관점
SEQUENCE 여러 필드를 순서대로 묶은 구조체 메시지 또는 IE의 기본 단위로 자주 등장합니다.
CHOICE 여러 후보 중 하나를 선택하는 구조 메시지 타입이나 확장 구조를 표현할 때 유용합니다.
OPTIONAL 존재할 수도 있고 없을 수도 있는 필드 decode 결과에서 필드가 누락되어도 오류가 아닐 수 있습니다.
INTEGER(0..1023) 정수 범위 제약 PER 계열 encoding에서는 값 범위가 bit 길이에 영향을 줍니다.
ASN.1 기본 문법 일러스트 SEQUENCE, CHOICE, OPTIONAL, CONSTRAINT가 메시지 구조를 구성하는 모습을 보여준다 ASN.1 Building Blocks 3GPP 메시지는 작은 타입 정의들이 계층적으로 조합되어 만들어집니다. SEQUENCE field list CHOICE one of many OPTIONAL may exist CONSTRAINT value range

그림 2. ASN.1 문법은 구조체, 선택지, 선택 필드, 값 제약을 조합해 메시지를 설명합니다.

4. Python 실습 준비

Python에서 ASN.1을 다루는 방법은 여러 가지가 있지만, 입문 단계에서는 asn1tools를 사용하면 schema를 compile하고 Python dictionary 형태의 값을 encode/decode하는 흐름을 빠르게 확인할 수 있습니다.

pip install asn1tools

개인적으로는 실제 3GPP ASN.1 파일을 바로 컴파일하려고 하기보다, 먼저 작은 schema를 직접 만들어보는 방식을 추천합니다. 실제 스펙 파일은 import 관계와 확장 문법이 많아서, 처음부터 접근하면 도구 문제인지 문법 이해 문제인지 구분하기 어렵습니다.

실제 3GPP ASN.1 파일을 바로 다루기 전에, 먼저 작은 학습용 schema로 전체 흐름을 이해하는 것이 좋습니다. 아래 예제는 3GPP 원문에서 가져온 것이 아니라, 블로그 설명을 위해 새로 만든 단순화된 toy schema입니다.

주의: 아래 ASN.1과 Python 코드는 학습용 예제입니다. 실제 3GPP RRC/NGAP 메시지 구조가 아니며, 특정 표준 문서의 ASN.1 모듈을 복제하지 않았습니다.

5. 학습용 ASN.1 Schema 작성

먼저 UE가 cell에 접속할 때 필요한 아주 단순한 정보를 표현한다고 가정해 보겠습니다. 실제 3GPP 메시지는 훨씬 복잡하지만, ASN.1의 핵심 문법을 익히기에는 아래 정도가 적당합니다.

Demo3GPP DEFINITIONS AUTOMATIC TAGS ::= BEGIN

UeIdentity ::= SEQUENCE {
    crnti        INTEGER (0..65535),
    shortName    IA5String (SIZE(1..16)) OPTIONAL
}

CellAccessInfo ::= SEQUENCE {
    pci          INTEGER (0..1007),
    band         INTEGER (1..1024),
    accessType   AccessType
}

AccessType ::= ENUMERATED {
    initialAccess(0),
    handover(1),
    resume(2)
}

DemoMessage ::= SEQUENCE {
    ue           UeIdentity,
    cell         CellAccessInfo,
    debugNote    IA5String OPTIONAL
}

END

여기서 DemoMessage는 가장 바깥쪽 메시지입니다. 내부에는 UE 식별 정보와 cell 접속 정보가 들어 있고, debugNote는 선택 필드입니다. 실제 프로토콜 분석에서도 “가장 바깥 메시지 → 내부 IE → 하위 타입” 순서로 따라가면 구조를 이해하기 쉽습니다.

6. Python으로 encode/decode 해보기

이제 위 schema를 Python 문자열로 넣고, UPER 방식으로 compile한 뒤 encode/decode를 수행해 보겠습니다. PER 계열 encoding은 ASN.1의 값 범위와 OPTIONAL 여부를 활용해 bit를 효율적으로 배치합니다.

import asn1tools

schema = """
Demo3GPP DEFINITIONS AUTOMATIC TAGS ::= BEGIN

UeIdentity ::= SEQUENCE {
    crnti        INTEGER (0..65535),
    shortName    IA5String (SIZE(1..16)) OPTIONAL
}

CellAccessInfo ::= SEQUENCE {
    pci          INTEGER (0..1007),
    band         INTEGER (1..1024),
    accessType   AccessType
}

AccessType ::= ENUMERATED {
    initialAccess(0),
    handover(1),
    resume(2)
}

DemoMessage ::= SEQUENCE {
    ue           UeIdentity,
    cell         CellAccessInfo,
    debugNote    IA5String OPTIONAL
}

END
"""

codec = asn1tools.compile_string(schema, "uper")

message = {
    "ue": {
        "crnti": 4660,
        "shortName": "UE-A"
    },
    "cell": {
        "pci": 321,
        "band": 78,
        "accessType": "initialAccess"
    },
    "debugNote": "lab"
}

encoded = codec.encode("DemoMessage", message)
decoded = codec.decode("DemoMessage", encoded)

print("encoded hex:", encoded.hex())
print("decoded:", decoded)

이 예제의 핵심은 결과 hex 값 자체가 아니라 동일한 schema가 encode와 decode의 기준점이 된다는 점입니다. 송신자와 수신자가 같은 ASN.1 정의와 같은 encoding rule을 사용해야 bit stream을 같은 의미로 해석할 수 있습니다.

7. 처리 흐름을 그림으로 이해하기

ASN.1 Python 처리 흐름 ASN.1 schema compile, Python dict encode, binary payload, decode, inspection으로 이어지는 흐름 Python ASN.1 Workflow 스펙 분석 자동화는 보통 아래 흐름으로 구성됩니다. ASN.1 schema compile asn1tools encode dict → bytes decode bytes → dict inspect debug Same schema + same encoding rule = same interpretation

그림 3. ASN.1 기반 분석 자동화는 schema compile, encode/decode, 결과 검증 흐름으로 진행됩니다.

8. 실제 3GPP ASN.1을 다룰 때 체크리스트

학습용 schema는 단순하지만, 실제 3GPP ASN.1은 release, extension marker, information object class, parameterization, import 관계 때문에 훨씬 복잡합니다. 따라서 실제 분석에서는 아래 항목을 먼저 확인하는 것이 좋습니다.

특히 실무에서 자주 막히는 지점은 “decode 함수 호출” 자체가 아니라, 어떤 ASN.1 모듈 버전을 써야 하는지, 최상위 PDU 타입을 무엇으로 잡아야 하는지, 그리고 캡처된 payload가 어떤 encoding rule로 만들어졌는지를 맞추는 과정입니다.

  1. 스펙 번호와 버전 확인: 같은 프로토콜이라도 Release와 버전에 따라 IE가 추가되거나 구조가 바뀔 수 있습니다.
  2. Encoding rule 확인: RRC, NGAP, F1AP 등 프로토콜별로 사용하는 PER 계열 규칙이 다를 수 있으므로 도구 설정을 먼저 확인해야 합니다.
  3. 최상위 PDU 타입 확인: decode를 시작할 ASN.1 type 이름이 무엇인지 알아야 합니다.
  4. Extension marker 확인: ... 이후 확장 필드는 release 변화와 호환성 분석에서 중요합니다.
  5. Tool 지원 범위 확인: Python 라이브러리가 ASN.1 전체 문법을 모두 지원하지 않을 수 있으므로, 실제 3GPP 모듈은 전처리나 전용 컴파일러가 필요할 수 있습니다.

9. 자주 하는 실수

실수 왜 문제가 되는가 대응 방법
schema 버전 불일치 필드 추가/삭제로 decode 결과가 틀어질 수 있습니다. 캡처 로그의 네트워크 release와 스펙 버전을 맞춥니다.
UPER/APER 혼동 같은 ASN.1이라도 bit alignment가 달라지면 결과가 달라집니다. 프로토콜별 encoding rule을 먼저 확인합니다.
최상위 type 오해 잘못된 type으로 decode하면 구조 자체가 맞지 않습니다. PDU 이름과 message direction을 확인합니다.
OPTIONAL 필드 오해 필드가 없다는 것이 항상 오류는 아닙니다. presence bit와 OPTIONAL 정의를 함께 봅니다.

10. 실무적으로는 어디에 쓰나?

Python ASN.1 처리는 단순한 encode/decode 실습을 넘어, 프로토콜 로그 분석과 테스트 자동화에 활용할 수 있습니다. 예를 들어 기지국 로그에서 RRC 메시지를 추출해 특정 IE가 존재하는지 확인하거나, 테스트용 PDU를 생성해 장비 동작을 검증하는 방식입니다.

Log Decoder

hex dump를 사람이 읽기 쉬운 dictionary 또는 JSON 형태로 변환합니다.

Regression Test

동일 메시지를 반복 생성하여 release 변경 후 decode 결과가 유지되는지 확인합니다.

IE Validation

필수 IE 존재 여부, 값 범위, enum 값 등을 자동으로 검사합니다.

Protocol Study

스펙의 메시지 구조를 직접 encode/decode하며 계층 구조를 빠르게 익힙니다.

마무리 요약

ASN.1은 3GPP 프로토콜 메시지를 이해하기 위한 중요한 도구입니다. Python을 사용하면 작은 schema부터 시작해 encode/decode 흐름을 빠르게 실험할 수 있고, 이후 실제 RRC나 NGAP 같은 메시지 분석으로 확장할 수 있습니다.

  • ASN.1은 메시지의 추상 구조를 정의하는 표기법입니다.
  • PER/UPER/APER는 ASN.1 구조를 이진 데이터로 바꾸는 encoding rule입니다.
  • 3GPP에서는 RRC, NGAP, F1AP, E1AP 등 다양한 프로토콜에서 ASN.1 구조를 만납니다.
  • Python에서는 asn1tools 같은 도구로 schema compile, encode, decode 흐름을 실습할 수 있습니다.
  • 실제 3GPP 분석에서는 스펙 버전, 최상위 PDU, encoding rule, tool 지원 범위를 반드시 확인해야 합니다.

참고자료

아래 자료는 본문을 작성할 때 개념 확인용으로 참고한 문서입니다. 본 게시물의 설명, 예제 ASN.1 schema, Python 코드, SVG 일러스트는 블로그 학습 목적에 맞게 새로 작성했습니다.

  • ITU-T X.680: Abstract Syntax Notation One (ASN.1) specification
  • 3GPP TS 38.331: NR Radio Resource Control (RRC)
  • 3GPP TS 38.413: NG Application Protocol (NGAP)
  • 3GPP TS 38.473: F1 Application Protocol (F1AP)
  • 3GPP TS 38.463: E1 Application Protocol (E1AP)
  • asn1tools documentation