| ASN.1 | |
|---|---|
| 抽象構文記法その1 | |
| 状態 | 有効。X.208およびX.209(1988年)に取って代わる。 |
| 年が始まった | 1984 |
| 最新バージョン | (02/21) 2021年2月 |
| 組織 | ITU-T |
| 委員会 | 研究グループ17 |
| 基本規格 | ASN.1 |
| 関連規格 | X.208、X.209、X.409、X.509、X.680、X.681、X.682、X.683 |
| ドメイン | 暗号学、電気通信 |
| Webサイト | https://www.itu.int/rec/T-REC-X.680/ |
抽象構文記法1(ASN.1 )は、クロスプラットフォームでシリアル化および逆シリアル化できるデータ構造を定義するための標準インターフェース記述言語(IDL)です。通信およびコンピュータネットワーク、特に暗号化において広く使用されています。[ 1 ]
プロトコル開発者は、ASN.1 モジュールでデータ構造を定義します。ASN.1 モジュールは通常、ASN.1 言語で記述されたより広範な標準文書の一部です。利点は、データエンコーディングの ASN.1 記述が特定のコンピュータやプログラミング言語に依存しないことです。ASN.1 は人間が読める形式と機械が読める形式の両方であるため、ASN.1 コンパイラはモジュールをコンパイルして、データ構造をデコードまたはエンコードするコードライブラリ(コーデック)を作成できます。一部の ASN.1 コンパイラは、packed、 BER、XMLなど、複数のエンコーディングをエンコードまたはデコードするコードを生成できます。
ASN.1 は、国際電気通信連合電気通信標準化部門(ITU-T) のITU-T 研究グループ 17と国際標準化機構/国際電気標準会議(ISO/IEC) の共同標準であり、元々は 1984 年に CCITT X.409 :1984の一部として定義されました。 [ 2 ] 1988 年に、ASN.1 は適用範囲が広いため、独自の標準X.208に移行しました。大幅に改訂された 1995 年版は、 X.680 – X.683シリーズでカバーされています。[ 3 ] X.680 シリーズ勧告の最新の改訂は、2021 年に発行された 6.0 版です。[ 4 ]
ASN.1はデータ型宣言表記法です。この表記法では、その型の変数を操作する方法は定義されていません。変数の操作は、実行可能モデリングのためのSDL(仕様記述言語)や適合性テストのためのTTCN-3(テストおよびテスト制御表記法)などの他の言語で定義されています。これらの言語はどちらもASN.1宣言をネイティブにサポートしています。ASN.1モジュールをインポートし、そのモジュールで宣言されている任意のASN.1型の変数を宣言することが可能です。
ASN.1は、多数のプロトコルを定義するために使用されています。その最も広範な用途は、電気通信、暗号化、および生体認証です。
ASN.1は、データ構造をバイト列として表現する方法を規定する一連のエンコーディング規則と密接に関連しています。標準的なASN.1エンコーディング規則には、以下のものが含まれます。
ASN.1勧告では、あらかじめ定義されたエンコーディング規則が多数提供されています。既存のエンコーディング規則がどれも適切でない場合、エンコーディング制御表記法(ECN、X.692)を用いることで、ユーザー独自のカスタマイズされたエンコーディング規則を定義できます。
プライバシー強化メール(PEM)エンコーディングは、ASN.1とそのコーデックとは全く関係ありませんが、多くの場合バイナリであるエンコードされたASN.1データは、SMTPリレーやコピー&ペーストバッファなどを介してテキストデータとして送信できるように、PEMエンコードされることがよくあります。
ASN.1言語およびエンコーディング仕様では、コンピュータ上にデータチャンクをファイルとして保存する際に使用するファイル名拡張子などの詳細は規定されていません。しかしながら、いくつかの慣習が生まれています。
.asn1[ 19 ]の拡張機能は.all一般的なファイルに使用されています。はモジュール定義のみを含むファイルに、は値定義のみを含むファイルに.asn使用されています。 [ 20 ].prt.berが使用されています。[ 21 ]また、関連付けられたOIDを指定するパラメータを含むMIMEタイプ も提案されています。 [ 22 ]application/ber-streamprotocol.der。DERエンコードされたX.509証明書の場合、.cerおよび.crtに加えて.der。MIMEタイプは、application/x-x509-ca-cert一般的なDERデータではなく、DERエンコードされた証明書専用です。asn1c使用されるサンプルファイル。.xer.per.coerこれは、架空のFooプロトコルのメッセージ(データ構造)を定義するASN.1モジュールの例です。
FooProtocol DEFINITIONS ::= BEGINFooQuestion ::= SEQUENCE { trackingNumber INTEGER , question IA5String }FooAnswer ::= SEQUENCE { questionNumber INTEGER , answer BOOLEAN }終わりこれはFooプロトコルの作成者によって公開された仕様である可能性があります。会話の流れ、トランザクションのやり取り、および状態はASN.1では定義されておらず、プロトコルの他の表記法やテキストによる説明に委ねられています。
ASN.1は値とサイズに関する制約と拡張性をサポートしています。上記の仕様は次のように変更できます。
FooProtocol DEFINITIONS ::= BEGINFooQuestion ::= SEQUENCE { trackingNumber INTEGER ( 0. . 199 ), question IA5String }FooAnswer ::= SEQUENCE { questionNumber INTEGER ( 10. . 20 ), answer BOOLEAN }FooHistory ::= SEQUENCE { questions SEQUENCE ( SIZE ( 0. . 10 )) OF FooQuestion , answers SEQUENCE ( SIZE ( 1. . 10 )) OF FooAnswer , anArray SEQUENCE ( SIZE ( 100 )) OF INTEGER ( 0. . 1000 ), ... }終わりこの変更により、trackingNumbers の値は 0 から 199 まで、questionNumbers の値は 10 から 20 までとなります。questions 配列のサイズは 0 から 10 要素、answers 配列は 1 から 10 要素です。anArray フィールドは、0 から 1000 の範囲の整数からなる固定長 100 要素の配列です。「...」拡張性マーカーは、FooHistory メッセージ仕様の将来のバージョンで追加のフィールドが追加される可能性があることを意味します。あるバージョンに準拠しているシステムは、後のバージョンのトランザクションを受信および送信できますが、以前のバージョンで指定されたフィールドのみを処理できます。優れた ASN.1 コンパイラは、(C、C++、Java などで)トランザクションがこれらの制約内に収まっていることを自動的にチェックするソース コードを生成します。制約に違反するトランザクションは、アプリケーションから受け入れられたり、アプリケーションに提示されたりしてはなりません。この層における制約管理は、アプリケーションが制約違反から保護されるため、プロトコル仕様を大幅に簡素化し、リスクとコストを削減します。
上記の例では、X.680の構文のみを使用しています。X.682のより高度な制約は使用していません。
Fooプロトコルに準拠し、受信側に送信されるメッセージを想定すると、この特定のメッセージ(プロトコルデータユニット(PDU))は次のようになります。
myQuestion FooQuestion ::= { trackingNumber 5 , question "誰かいますか?}myQuestionメッセージをネットワーク経由で送信するには、メッセージはエンコード規則のいずれかを使用して一連のバイトとしてシリアル化(エンコード)されます。Fooプロトコルの仕様では、使用するエンコード規則のセットを明示的に指定する必要があります。そうすることで、Fooプロトコルのユーザーは、どのエンコード規則を使用すべきか、またどのようなエンコード規則を期待すべきかを把握できます。
上記はX.681の例であり、具体的にはObjectAssignment構造の例です。
以下は、上記のデータ構造をDER 形式でエンコードした myQuestion です(すべての数値は 16 進数です)。
30 13 02 01 05 16 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f
DERは型-長さ-値のエンコーディングであるため、上記のシーケンスは、標準のSEQUENCE、INTEGER、およびIA5String型を参照して、次のように解釈できます。
30 — シーケンスを示すタイプタグ 13 — 続く値のオクテット単位の長さ 02 — 整数を示すタイプタグ 01 — 続く値のオクテット単位の長さ 05 — 値 (5) 16 — IA5Stringを示すタイプタグ (IA5 は、バリアントを含む完全な 7 ビット ISO 646 セットを意味します。 ただし、一般的にはUS-ASCIIです。 0e — 続く値のオクテット単位の長さ 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f — 値(「誰かいますか?」)
あるいは、同じASN.1データ構造をXMLエンコーディングルール(XER)でエンコードすることで、ネットワーク上での可読性を向上させることも可能です。その場合、以下の108オクテット(インデントに使用されるスペースを含む)として表示されます。
<FooQuestion> <trackingNumber> 5 </trackingNumber> <question>誰かいますか?</question> </FooQuestion>あるいは、パックエンコード規則非アラインメントが採用された場合、次の122ビット(16オクテットで128ビットになりますが、ここでは122ビットのみが情報を保持し、最後の6ビットは単なるパディングです)が生成されます。
01 05 0e 83 bb ce 2d f9 3c a0 e9 a3 2f 2c af c0
この形式では、必須要素のタイプ タグはエンコードされないため、エンコードに使用される想定スキーマがわからないと解析できません。さらに、IA5String の値のバイトは 8 ビット単位ではなく 7 ビット単位でパックされます。これは、エンコーダが IA5String バイト値のエンコードには 7 ビットしか必要ないことを知っているためです。ただし、長さバイトは最初の整数タグ 01 に対してもエンコードされます (ただし、PER パッカーは、許容値の範囲が 8 ビットに収まることを知っていればそれを省略することもできますし、許容値がより小さな範囲にしか収まらないことを知っていれば、単一の値バイト 05 を 8 ビット未満に圧縮することもできます)。
エンコードされたPERの最後の6ビットは、最後のバイトc0の最下位6ビットにヌルビットでパディングされます 。このシーケンスがより長い非整列PERシーケンスの一部として挿入される場合、これらの余分なビットは送信されないか、他のもののエンコードに使用されない可能性があります。
これは、アラインメントされていない PER データは、アラインメントされた PER のようにバイトの順序付けされたストリームではなく、本質的にビットの順序付けされたストリームであることを意味し、通常のプロセッサでソフトウェアによるデコードがやや複雑になります。これは、直接バイト アドレス指定ではなく、追加のコンテキスト ビット シフトとマスキングが必要となるためです (ただし、最小アドレス指定単位が 1 オクテットより大きい最新のプロセッサとメモリ/ストレージ ユニットでも同様のことが言えます)。ただし、最新のプロセッサと信号プロセッサには、アドレス指定可能なストレージ ユニットの境界を越える計算ユニットを自動的に処理する、ビット ストリームの高速内部デコードのためのハードウェア サポートが含まれています (これは、圧縮/解凍用のデータ コーデックや一部の暗号化/復号化アルゴリズムでの効率的な処理に必要です)。
比較のために、パックエンコーディングルールを揃えた場合、代わりに以下の結果が得られます。
01 05 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f
このフォーマットはオクテット境界に揃えられています。この場合、各オクテットの未使用の最上位ビットには、それぞれヌルビットが個別にパディングされます。
ASN.1をサポートするツールのほとんどは、以下の機能を備えています。
ASN.1をサポートするツールの一覧は、ITU-Tツールのウェブページで確認できます。
ASN.1は、クロスプラットフォームのデータシリアライゼーションのためのインターフェース記述言語であるGoogle Protocol BuffersやApache Thriftと目的や用途が似ています。これらの言語と同様に、スキーマ(ASN.1では「モジュール」と呼ばれます)と、通常は型-長さ-値のエンコーディングである一連のエンコーディングを備えています。しかし、ASN.1は、すぐに使用できる単一のオープンソース実装を提供せず、サードパーティベンダーが実装するための仕様として公開されています。ただし、1984年に定義されたASN.1は、これらの言語よりも何年も前に存在しています。また、より多様な基本データ型(一部は廃止されています)を含み、拡張性に関するオプションも豊富です。単一のASN.1メッセージには、複数の標準で定義された複数のモジュールからのデータを含めることができ、それらの標準は数年離れて定義されている場合もあります。
ASN.1には、値とサイズに関する制約を組み込んだサポートも含まれています。例えば、モジュールは、0から100の範囲でなければならない整数フィールドを指定できます。値のシーケンス(配列)の長さも、固定長または許容される長さの範囲として指定できます。制約は、基本制約のセットの論理的な組み合わせとして指定することもできます。
制約として使用される値は、PDU仕様で使用されるリテラル、またはスキーマファイル内の別の場所で指定されるASN.1値のいずれかです。一部のASN.1ツールでは、生成されたソースコードでこれらのASN.1値をプログラマが利用できるようにします。定義中のプロトコルの定数として使用されるこれらの値は、開発者がプロトコルのロジック実装で使用できます。したがって、すべてのPDUとプロトコル定数をスキーマで定義でき、サポートされている言語でのプロトコルのすべての実装はこれらの値を使用します。これにより、開発者が実装のソースコードでプロトコル定数を手動でコーディングする必要がなくなります。これはプロトコル開発を大幅に支援します。プロトコルの定数はASN.1スキーマで変更でき、すべての実装は再コンパイルするだけで更新されるため、迅速かつ低リスクの開発サイクルが促進されます。
ASN.1 ツールが生成されたソース コードに制約チェックを適切に実装すれば、プログラム実行中にプロトコル データを自動的に検証できます。一般的に、ASN.1 ツールは生成されたシリアル化/逆シリアル化ルーチンに制約チェックを含め、範囲外のデータが見つかった場合はエラーまたは例外を発生させます。ASN.1 コンパイラで ASN.1 制約のすべての側面を実装するのは複雑です。すべてのツールが可能な制約式の全範囲をサポートしているわけではありません。XMLスキーマとJSON スキーマはどちらも同様の制約概念をサポートしています。制約に対するツールのサポートは様々です。Microsoft の xsd.exe コンパイラは制約を無視します。
一部のASN.1ツールは、ASN.1とXMLスキーマ(XSD)間の変換が可能です。この変換はITUによって標準化されています。これにより、プロトコルをASN.1で定義し、同時にXSDでも自動的に定義することが可能になります。したがって、(おそらく推奨されませんが)プロジェクト内でXSDスキーマをASN.1ツールでコンパイルし、オブジェクトをJSONワイヤフォーマットにシリアル化するソースコードを生成することができます。より実用的な用途としては、他のサブプロジェクトがASN.1スキーマの代わりにXSDスキーマを使用できるようにし、サブプロジェクトで使用されている言語に対応したツールを利用できるようにすることなどが挙げられます。この場合、プロトコルワイヤフォーマットとしてXERが使用されます。
OSS Nokalvaは、JSONデータオブジェクトまたはJSONスキーマをASN.1定義に変換するツールを提供しています。[ 23 ] ASN.1データ構造のJERエンコード構造を記述するJSONスキーマを生成するツールはまだありません。
OSS Nokalvaは、Protocol BuffersスキーマをASN.1定義に変換するツールも提供しています。[ 24 ]
多くのプログラミング言語は、言語固有のシリアル化フォーマットを定義しています。例えば、Pythonの「pickle」モジュールやRubyの「Marshal」モジュールなどが挙げられます。これらのフォーマットはスキーマを必要としません。一般的に言語固有のフォーマットであるため、アドホックなストレージ用途には適していますが、通信プロトコルには不向きです。
JSONとXMLはどちらもスキーマを必要としないため、使いやすい。また、どちらもクロスプラットフォーム標準であり、特にJSONスキーマやXMLスキーマと組み合わせた場合、通信プロトコルとして広く普及している。
ASN.1は、 HTTPやSMTPなどの多くのインターネットプロトコルを定義するために使用される拡張バッカス・ナウア記法(ABNF)と視覚的に似ています。しかし、実際には両者は大きく異なります。ASN.1は、さまざまな方法(JSON、XML、バイナリなど)でエンコードできるデータ構造を定義します。一方、ABNFは、データ構造(意味論)を定義すると同時に、エンコード(構文)も定義します。ABNFは、テキスト形式の人間が読みやすいプロトコルを定義する際によく使用され、一般的には型・長さ・値のエンコードを定義するために使用されません。
ASN.1は視覚的にもCSN.1とよく似ています。しかし、CSN.1はオブジェクトのエンコーディング、特にビットレベルでのエンコーディングも定義しています。