繁体   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