我需要解析到我的Java项目中的二进制ASN.1数据对象。我只想要ASN.1结构和数据,例如由BER查看器解析:
BouncyCastle的ASN.1解析器无法解析此结构(仅返回特定于应用程序的二进制数据类型)。
我可以用什么ASN.1库来获得这样的结果?有没有人有示例代码来演示如何解析ASN.1对象?
BTW:我还尝试了几个免费的ASN.1 Java编译器,但是没有一个能够生成ASN.1规范给出的可用的Java代码。答案 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.BerDecoder和com.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));
结果是打印结构,但在八位字节串中,它是打印长度而不是值。 如何打印价值?