簡體   English   中英

Opensource Java ASN.1解碼器,可以使用自動標簽

[英]Opensource Java ASN.1 decoder that work with automatic tags

我剛開始使用ASN.1編碼流,我很難找到一個免費的類編譯器和解碼器,最好是Java。

我有一個編碼的十六進制字符串

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/它沒有說它是否支持自動標簽。 它似乎在沒有抱怨的情況下編譯Notation,但是我無法正確解碼它看起來像標記錯誤。

如果我們采用編碼字符串的開頭: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忽略了。 當我查看生成的Java類時,我們看到SemiDialogID擴展了BerEnum,它使用了通用clas標識符:

// 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來使其工作。

這是一個非常臟的黑客,讓jASN1使用自動標簽。 這不是一般解決方案,需要花費大量時間手動編輯所有生成的類,因此我仍在尋找完整的解決方案。

在方法中不同Sequences的生成類中:

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類,標記號是通用類型之一或類似構造序列的類。 您可以通過打印出已解碼的標識符和預期的標識符來快速查看差異:

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

因此,您可以強制預期標識符對於自動標記是正確的,將Class設置為CONTEXT_CLASS,最后的整數,標記號,t是序列中字段的索引:

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

一些警告:在大型協議中,需要花費大量時間來完成所有相關的解碼步驟。 這很容易出錯。 對協議的更改需要重新生成類並合並將會很痛苦的更改。 以上都不涉及編碼。 我還沒有完全測試過所有內容,但我相信這是唯一需要進行的更改。

所以,是的,請繼續發布任何建議,但我希望上述內容對任何真正陷入困境並需要快速入侵的人都有用。

從版本1.6.0開始,jASN1支持自動標記。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM