web-dev-qa-db-ja.com

openSSLのASN.1カプセル化BITSTRINGタイプ

私は現在、ASN.1 DER形式のX.509v3証明書とエポックファイルをデコードすることになっているASN.1パーサーを構築しています。パーサーは、私が得ることができなかった1つの問題とは別にうまく機能しています。 DER形式をデコードすると、公開鍵に次の形式のBITSTRINGが使用されていることがわかります。

 BIT STRING, **encapsulates** {

 SEQUENCE {

 INTEGER

     // public key hex string

しかし、署名を見ると、それはencapsulatesタグなしのBITSTRINGで表されており、署名の16進バッファーのみが含まれていることがわかります。

 SEQUENCE {

 OBJECT IDENTIFIER sha256WithRSAEncryption (1 2 840 113549 1 1 11)   

 NULL

 } 

 BIT STRING 

 // RAW signature hex buffer }

パーサーにとって、BITSTRINGがバッファーのみを含むか(署名の場合など)、他のいくつかのタイプをカプセル化するか(公開鍵の場合など)を知ることが重要です。両方のDERエンコーディングでは、カプセル化の使用を示唆するような違いは見つかりませんでした。

私の質問:パーサーコードでこれらの2つのシナリオをどのように区別できますか?

3
Dima Shifrin

解析しているデータの種類を知らなければ、それを本当に知ることはできません。

デコードするデータのタイプがわかっている場合は、ASNモジュールと関連ドキュメントを使用してパーサーを調整する必要があります。さらに、いくつかの知的作業を行う必要がある場合があります。

bITSTRINGにはバッファのみが含まれます(署名の場合と同様)。

これは生のバッファではなく、ネストされたタイプの場合もあります。たとえば、ECDSA署名を見ると、エンコードされた署名がネストされた複合型であることがわかります。

ECDSA-Sig-Value ::= SEQUENCE {
    r  INTEGER,
    s  INTEGER
   }

そしてここにそれがどのように見えるかです: enter image description here

または他のいくつかのタイプをカプセル化します(公開鍵の場合のように)

繰り返しますが、常にではありません。 RSAキーはBIT_STRINGでネストされた構造を使用しますが、ECキーは次のことを行いません: enter image description here

これらは、仮定が失敗する例にすぎません。署名にはネスト構造があり、公開鍵にはそれがない場合があります。それはコンテキストに依存し、ドキュメンテーションがないと何を期待するのかわかりません。したがって、ドキュメントを使用することをお勧めします。たとえば、ほとんどのPKIX ASNモジュールを含む RFC5912 です。

解析しているデータがわからない場合は、現在の型がプリミティブであるか、または構築されているか(CONSTRUCTEDビットセットなし)をプロアクティブにチェックするために、大変な作業を行う必要があります。可能であれば、ネストされた型を展開しようとします。

C#で記述された離散構造にASNバイナリデータをデコードする汎用の生のパーサーがあります: Asn1DerParser.NET およびパーサークラス: Asn1Reader

3
Crypt32

BIT STRINGは、「値はビットのシーケンスである」という基本的なタイプであり、これらのビットの解釈方法に関する追加情報はまったくありません。値ビット自体がネストされた構造のDERエンコーディングであると想定されるか、「単なるビット」であるかによって、エンコーディングに違いはありません。

「通常の」答えは@ Crypt32によって与えられたものです。構造(X.509証明書など)をデコードするとき、デコードする構造の種類を知っているはずであり、それに応じて動作します。これは実際にはかなり複雑になる可能性があります。たとえば、SubjectPublicKeyInfo構造体には、公開鍵のタイプを識別するAlgorithmIdentifierと、公開鍵の値を含むBIT STRINGが含まれています。公開鍵がRSA鍵の場合、BIT STRINGの値はDERエンコードされた構造(2つのSEQUENCEINTEGER)であると想定されます。ただし、これがEC公開鍵の場合、BIT STRINGの包含は、ASN.1またはDERのない、エンコードされた生の公開ポイントになります。

ツールが診断用である場合、ヒューリスティックを使用できます。一般的なASN.1/DERパーサーである DDer を確認することをお勧めします(実際には、BERをサポートしています)。 「バイナリ値」(BIT STRINGまたはOCTET STRING)を検出すると、その値自体がASN.1オブジェクトとしてデコードできるかどうかを確認しようとします。 BER/DERエンコーディングは非常に冗長であるため、署名のような任意のランダムな値がDERエンコーディングとエラーなしで一致することはほとんどありません(基本的には10000回に1回程度)。

(DDerには、テキストベースの表現からDERエンコーディングへの逆の操作を行うMDerと呼ばれる関連ツールも付属しています。これは、テストオブジェクトの作成に便利です。)

1
Thomas Pornin

ビット文字列とオクテット文字列の両方に、データまたは埋め込みASN.1を含めることができます。構文解析の前に、どのフォーマットをとるべきかを知るのに役立ちますが、それは必ずしも必要ではありません。 (これらのASN.1デコーダーは、完全に解析する前に何をデコードするかを認識していません。)オクテット文字列を解析するときは、単に内容を見て、それがASN.1プリミティブ(1バイトのヘッダー、その後にサイズ情報が続き、その後にサイズで示されるデータ量が続きます)。

ビット文字列は、分析が少し複雑です。ビット文字列には、オフセットビットの数を示すバイトが含まれます。ビット文字列はバイト単位で保持されますが、オブジェクトに格納される実際のビット数は、8の倍数から1〜7の範囲になります。オフセットは0です。含まれているバイトを見て、含まれているデータがASN.1プリミティブであるかどうかを評価できます。

0
Lampshade