【问题标题】:Parsing ASN.1 binary data with Java用 Java 解析 ASN.1 二进制数据
【发布时间】:2012-04-17 11:57:57
【问题描述】:

我有二进制 ASN.1 数据对象,我需要将其解析到我的 Java 项目中。我只想要 ASN.1 结构和数据,例如由 BER 查看器解析:

BouncyCastle 的 ASN.1 解析器无法解析此结构(仅返回应用程序特定的二进制数据类型)。

我可以使用什么 ASN.1 库来获得这样的结果?有人有演示如何解析 ASN.1 对象的示例代码吗?

顺便说一句:我还尝试了几个免费的 ASN.1 Java 编译器,但没有一个能够生成给定 ASN.1 规范的工作 Java 代码。

【问题讨论】:

  • 你只是想解析一个BER数据流,还是想实现特定的ASN.1语法?
  • 我有一个 ASN.1 语法,但我测试的 ASN.1 编译器不接受它。无论如何,我宁愿不局限于那些我有语法的对象。

标签: java parsing asn.1


【解决方案1】:

我必须纠正自己 - 可以使用 BouncyCastle 中包含的 ASN.1 解析器读取数据 - 但过程并不那么简单。

如果您只想打印包含在 ASN.1 结构中的数据,我建议您使用 org.bouncycastle.asn1.util.ASN1Dump 类。可以通过下面的简单代码sn-p来使用:

ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(data));
ASN1Primitive obj = bIn.readObject();
System.out.println(ASN1Dump.dumpAsString(obj));

它打印结构而不是数据 - 但是通过将 ASN1Dump 复制到自己的类中并修改它以打印出例如 OCTET_STRINGS 可以轻松完成。

另外,ASN1Dump 中的代码演示了解析 ASN.1 结构。例如,我的问题中使用的数据可以使用以下代码更深入地解析:

DERApplicationSpecific app = (DERApplicationSpecific) obj;
ASN1Sequence seq = (ASN1Sequence) app.getObject(BERTags.SEQUENCE);
Enumeration secEnum = seq.getObjects();
while (secEnum.hasMoreElements()) {
    ASN1Primitive seqObj = (ASN1Primitive) secEnum.nextElement();
    System.out.println(seqObj);
}

【讨论】:

    【解决方案2】:

    只需使用“true”来打印值

        ASN1InputStream ais = new ASN1InputStream(
            new FileInputStream(new File("d:/myfile.cdr")));
        while (ais.available() > 0) {
            ASN1Primitive obj = ais.readObject();
            System.out.println(ASN1Dump.dumpAsString(obj, true));
        }
        ais.close();
    

    【讨论】:

    • 仅供参考:带有两个参数的 dumpAsString 在较旧的 bo​​uncycastle 版本中不可用。
    【解决方案3】:

    从您的问题中不清楚您是否具有您尝试解析的 BER 的 ASN.1 规范。请注意,如果没有 ASN.1 规范,如果在生成数据的 ASN.1 规范中使用了显式标签,则只能部分理解数据。一些工具,例如来自OSS Nokalva 的工具,有一个名为 JIAAPI 的库(jar 文件),它允许您在不了解 ASN.1 规范的情况下遍历和操作 BER 编码。

    如果您确实有 ASN.1 规范,那么任何 ASN.1 Java 编译器都应该能够处理这个问题。

    您可以从http://www.oss.com/asn1/products/asn1-download.html 下载适用于 Java 的 OSS ASN.1 工具的免费试用版,看看是否比您尝试失败的其他工具更适合您。

    【讨论】:

      【解决方案4】:

      我需要能够解析 krypt 中任何类型的 ASN.1 数据。虽然 krypt 是一个 Ruby 项目,但您可能想看看 JRuby extension - 处理 ASN.1 解析/编码的代码完全用 Java 编写,并且足够模块化以便于提取。

      我也做了一个Java-only version,但它缺少了前者的一些高级功能。但既然它很简洁,也许这是一个让你开始的好机会。

      【讨论】:

      • 您的代码看起来不错 - 不幸的是,我注意到我不仅需要 ASN.1 解析器/反序列化器,还需要序列化部分。
      • 谢谢!当我开始将它集成到 krypt 中时,我停止推进纯 Java 版本,在那里,你还会找到 serialization bits。整个 impl 包是独立的,所以它不会与 JRuby 的细节混杂在一起——你应该能够轻松地提取它。
      【解决方案5】:

      如果您只想对 BER 编码的数据进行解码,可以使用许多解析器。你试过吗? Sun JDK 中甚至还有两个 - com.sun.jmx.snmp.BerDecodercom.sun.jndi.ldap.BerDecoder

      【讨论】:

      • 注意:com.sun.* 包中的 JDK 类不是公共 API,可以在未来的版本中删除/更改。
      • @Tom:我会试试这些类,但这些类的文档与其他几个 ASN.1 项目的文档一样好:几乎不存在...
      • 文档不是很理想,但是类很简单,可以通过OpenJDK获取源代码。我想你可以通过阅读和实验来学习你需要知道的一切。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-31
      • 2011-11-23
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多