D   A   T   A   W   O   K

Creation: March 02 2017
Modified: January 01 2019

Abstract Syntax Notation 1


ASN.1 is a standard notation syntax defined in ITU-T X.680 to describe rules and structures for representing data in telecommunications and computer networking.

ASN.1 itself does not mandate any encoding or parsing rules, but usually ASN.1 data structures are encoded using the Basic Encoding Rules (BER), described in ITU-T X.690, or the Distinguished Encoding Rules (DER), a subset of BER.

There is generally more than one way to BER-encode a given value but there is only one way to DER-encode it.

The formal rules enable representation of objects that are independent of a machine-specific encoding techniques. Thus facilitates the exchange of structured data, particularly between programs separated by networks.

DER and BER encodings are binary Tag-Length-Value (TLV) encodings that are quite concise compared to other popular description formats such as XML, JSON, etc.


Types and Values

In ASN.1, a type is a set of values. For some types, there are a finite number of values, and for other types there are an infinite number. A value of a type is an element of the type's set.

There are four kinds of type:

Types and values can be given names with the ASN.1 assignment operator (::=), and those names can be used in defining other types and values.

Every type, other than CHOICE and ANY has a tag, which consists of a class and a non negative tag number. There are four classes of tag:

Types with universal tags are defined in X.208, which also gives the types universal tag numbers. Some common types and their universal-class tags:

Type Tag
SET and SET OF 17
PrintableString 19
IA5String 22
UTCTime 23

Simple types

Relevant types, for PKCS standards, are:

Simple types fall into two categories: string types and non-string types. The string types can be given size constraints limiting the length of values.

Structured types

ASN.1 defines four.

Structured types can have optional components, possibly with default values.

Tagged types

Tagging is useful to distinguish component types within an application; it is also commonly used to distinguish component types within a structured type. For instance, optional components of a SET or SEQUENCE type are typically given distinct context-specific tags to avoid ambiguity.

There are two ways to tag a type: implicitly and explicitly. Implicitly tagged types are derived from other types by changing the tag of the underlying type. Explicitly tagged types are derived from other types by adding an outer tag to the underlying type. In effect, explicitly tagged types are structured types consisting of one component, the underlying type.

ASN.1 syntax for implicit tagged type [class number] IMPLICIT

ASN.1 syntax for explicit tagged type [class number] EXPLICIT

When not specified, the keyword [class number] alone, defaults to explicit, except when the "module" in which the ASN.1 type is defined has implicit tagging by default.

For purposes of encoding, an implicitly tagged type is considered the same as the underlying type, except that the tag is different.

Implicit tags result in shorter encodings, but explicit tags may be necessary to avoid ambiguity if the tag if the underlying type is indeterminate (e.g. the underlying type is CHOICE or ANY).

Other types

Other types include the CHOICE and ANY types. CHOICE type denotes a union of one or more alternatives; the ANY type denotes an arbitrary value of an arbitrary type.


Data structures of (a fictitious) Foo Protocol defined using ASN.1 notation:


FooQuestion ::= SEQUENCE
    id          INTEGER(0..255),
    question    VISIBLE STRING

FooAnswer ::= SEQUENCE
    id          INTEGER(0,255),
    answer      BOOLEAN