2016-05-05 15 views
4

ASN.1でエンコードされたストリームを扱うのが初めてで、Java用の無料クラスコンパイラとデコーダを見つけるのは難しいです。Opensource自動タグで動作するJava ASN.1デコーダ

私はエンコードされた16進文字列があります。ここでは

String test("30820274800200a2810105820410300c3d830401bb0afc84... 

は、表記の例です:

SEMI DEFINITIONS AUTOMATIC TAGS ::= BEGIN 

IntersectionSituationData ::= SEQUENCE { 
    dialogID  SemiDialogID,     -- 0xA2  
    seqID   SemiSequenceID,     -- 0x05 Data 
    groupID   GroupID,       
    -- Some more members 
} 

SemiDialogID ::= ENUMERATED { 
    intersectionSitDataDep  (162), -- 0xA2 
    -- additional DialogIDs 
} 
SemiSequenceID ::= ENUMERATED { 
    data    (5), -- Data 
    -- additional SeqIDs 
} 

私はJAC使用して開始しました:https://sourceforge.net/projects/jac-asn1/ をしかし、それは自動タグをサポートしていません。

次はjASN1を試しました:https://www.openmuc.org/asn1/ 自動タグをサポートしているかどうかはわかりません。それは、不平を言って表記をコンパイルするようですが、私はそれを正しく解読することができませんし、間違っていればタグ付けのように見えます。

我々はエンコードされた文字列の先頭取る場合: ... 30 82 02 74 80 02 00 A2をこれが私の理解です:

30 = Sequence 
82 = Length encoded in 2 octets 
02 74 = Length = 2x256 + 7x16 +4 == 638 bytes, correct 
80 ?? is this a result of automatic encoding? x80= 128= 8th bit set = context-specific class, number 0? 
02 = length of value is 2 octets 
00 a2 is value == xA2 as expected from SemiDialogID 

しかし、私は "IntersectionSituationData" のテストをエンコードする場合、私は取得次のようになります:30 81 8a 0a 02 00 a2 つまり、タイプは 'x0a' == 10です。これはASN.1 Universal ENUMERATEDです。それは彼の通知を見てフォームを意味するが、私は推測している自動タグはjASN1によって無視されている。私たちはSemiDialogIDユニバーサルCLAS識別子を使用していますBerEnumを、拡張参照生成されたJavaクラスを見てみると:

// SemiDialogID.java 
public class SemiDialogID extends BerEnum { 
    ... 
} 

//BerEnum.java 
public class BerEnum extends BerInteger { 

    public final static BerIdentifier identifier = new BerIdentifier(BerIdentifier.UNIVERSAL_CLASS, 
     BerIdentifier.PRIMITIVE, BerIdentifier.ENUMERATED_TAG); 

私はjASN1自動タグを動作させるために行う必要があるか、私は別のライブラリを必要としないものがありますか?後者の場合、人々は何をお勧めしますか?理想的には、私は使いやすいオープンソースのJavaソリューションを探しています。私はCのソリューションを使って、JNIを使​​って動作させることができたと思います。

答えて

1

ここでは、自動タグでjASN1を動作させるための非常に汚いハックです。これは一般的な解決策ではなく、生成されたすべてのクラスを手動で編集するのに多くの時間がかかるため、私はまだ完全な解決策を探しています。あなたはこのようないくつかのコードが表示されます

public int decode(InputStream is, boolean explicit) throws IOException { 

、タグ/識別子チェックされています:例外がスローされ

if (berIdentifier.equals(MsgCount.identifier)) { 
     msgCnt = new MsgCount(); 
     subCodeLength += msgCnt.decode(is, false); 
     subCodeLength += berIdentifier.decode(is); 
    } 
    else { 
     throw new IOException("Identifier does not match the mandatory sequence element identifer."); 
    } 

の方法では、異なる配列のために生成されたクラス内

識別子が一致しないためです。生成されたクラスは、通常、ASN Universalクラスを想定しています。タグ番号は、汎用型のいずれか、または構成されたシーケンスのようなものです。 CONTEXT_CLASS、そして最終的にするクラスを設定し、

System.out.println("Decoded: " + berIdentifier + ", expected: " + MsgCount.identifier); 

あなたはそのため、自動タグについて正しいことが期待される識別子を強制することができます:あなたはすぐに復号化された識別子と予想される識別子をプリントアウトして差分を見ることができます

BerIdentifier identifier2 = new BerIdentifier(BerIdentifier.CONTEXT_CLASS, BerIdentifier.PRIMITIVE, 2); // Hardcode the true idenifier 
if (berIdentifier.equals(identifier2)) { // Check the decoded identifier matches our hard-coded value, instead of the generated 
     msgCnt = new MsgCount(); 
     ... // Carry on as before 

いくつかの注意点:それは、関連するデコードステップをすべて通過する多くの時間がかかる大規模なプロトコルでは、整数、タグ番号は、tはシーケンス内のフィールドのインデックスです。これはエラーが発生しやすいです。プロトコルを変更するには、クラスを再生成し、変更をマージする必要があります。これは苦痛になります。上記のいずれもエンコーディングに関するものではありません。私はすべてを完全にテストしていませんが、これが唯一必要な変更だと私は信じています。

だから、提案を残しておいてください。しかし、私は上記が本当に立ち往生し、素早くハックする必要がある人にとっては便利だと思います。

1

バージョン1.6.0以降、jASN1は自動タグ付けをサポートしています。

関連する問題