使用Java解析ASN.1二进制数据

时间:2012-04-17 11:57:58

标签: java parsing asn.1

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

ASN.1 structure as shown in BER viewer

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

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

BTW:我还尝试了几个免费的ASN.1 Java编译器,但是没有一个能够生成ASN.1规范给出的可用的Java代码。

6 个答案:

答案 0 :(得分:17)

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

如果您只想打印ASN.1结构中包含的数据,我建议您使用类org.bouncycastle.asn1.util.ASN1Dump。它可以被以下简单的代码片段使用:

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);
}

答案 1 :(得分:4)

只需使用" 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();

答案 2 :(得分:3)

从您的问题中不清楚您是否对要尝试解析的BER具有ASN.1规范。请注意,如果没有ASN.1规范,只有在生成它的ASN.1规范中使用了EXPLICIT TAGS时,才能部分了解数据。某些工具(例如来自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工具的免费试用版,看看是否比您尝试失败的其他工具更适合您。

答案 3 :(得分:2)

如果您只想解码BER编码数据,那里有许多解析器。你尝试过吗? Sun JDK中甚至有两个 - com.sun.jmx.snmp.BerDecodercom.sun.jndi.ldap.BerDecoder

答案 4 :(得分:2)

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

我还制作了Java-only version,但它缺少前者的一些高级功能。但由于它简洁,也许这是一个让你入门的好机会。

答案 5 :(得分:1)

我使用bouncycastle API打印字符串结构,下面是代码片段:

ASN1InputStream bIn = new ASN1InputStream(input);
    DERObject obj = bIn.readObject();
    System.out.println(CustomTreeNode.dumpAsString(obj));

结果是打印结构,但在八位字节串中,它是打印长度而不是值。 如何打印价值?