用Java解析ASN.1二进制数据
我有需要解析到我的Java项目中的二进制ASN.1数据对象。 我只想要ASN.1结构和数据,例如BER查看器解析它:
BouncyCastle的ASN.1解析器无法解析此结构(仅返回特定于应用程序的二进制数据类型)。
我可以使用什么ASN.1库来获得这样的结果? 有没有人有示例代码来演示如何解析ASN.1对象?
顺便说一句:我还尝试了几个免费的ASN.1 Java编译器,但没有一个能够生成ASN.1规范给出的工作Java代码。
我必须纠正自己 – 可以使用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); }
只需使用“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();
从您的问题中不清楚您是否具有要尝试解析的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工具的免费试用版,以查看是否比您尝试失败的其他工具更适合您。
我需要能够解析krypt中的任何类型的ASN.1数据。 虽然krypt是一个Ruby项目,但您可能希望查看JRuby扩展 – 处理ASN.1解析/编码的代码完全用Java编写,并且模块化足以轻松提取。
我还制作了一个仅限Java的版本 ,但它缺少前者的一些高级function。 但由于它简洁,也许这是一个让你入门的好机会。
如果您只想解码BER编码数据,那里有许多解析器。 你尝试过吗? Sun JDK中甚至还有两个 – com.sun.jmx.snmp.BerDecoder和com.sun.jndi.ldap.BerDecoder 。
我使用bouncycastle API来打印字符串结构,下面是代码片段:
ASN1InputStream bIn = new ASN1InputStream(input); DERObject obj = bIn.readObject(); System.out.println(CustomTreeNode.dumpAsString(obj));
结果它是打印结构,但在八位字节串中它是打印长度而不是值。 如何打印价值?