2012-04-17 1770 views
20

我有我需要解析到Java项目中的二进制ASN.1数据对象。我只是想ASN.1结构和数据,因为它是由BER观众解析例如:用Java解析ASN.1二进制数据

ASN.1 structure as shown in BER viewer

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

我可以使用哪些ASN.1库得到这样的结果呢?有没有人有示范代码演示如何解析ASN.1对象?

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

+0

你只是想分析BER数据流,或者你想实现一个特定的ASN.1语法? – 2012-04-17 12:22:10

+0

我有一个ASN.1语法,但我测试的ASN.1编译器不接受它。无论如何,我宁愿不受限于那些我拥有语法的对象。 – Robert 2012-04-17 12:44:15

回答

15

我必须纠正自己 - 这是可以读出使用包含在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

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

+4

注意:com.sun。*包中的JDK类不是公共API,可以在将来的版本中删除/更改。 – Puce 2012-04-17 12:26:28

+0

@Tom:我会试试这些类,但这些类的文档与其他几个ASN.1项目的文档一样好:几乎不存在... – Robert 2012-04-17 12:42:03

+0

文档不理想,但类是简单,您可以通过OpenJDK获取源代码。我会想象你可以通过阅读和实验了解你需要知道的一切。 – 2012-04-17 17:17:25

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工具的免费试用版,以查看您是否比您尝试失败的其他版本更适合您。

2

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

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

+0

你的代码看起来不错 - 不幸的是我注意到我不仅需要一个ASN.1解析器/解串器,而且还需要序列化部分。 – Robert 2012-05-02 18:19:24

+0

谢谢!当我开始将它集成到krypt中时,我停止推进纯Java版本,在那里,您还将找到[序列化位](https://github.com/emboss/krypt-core-java/tree/master/src/ IMPL/krypt/ASN1)。整个impl包是独立的,所以它不会与JRuby特性混合在一起 - 您应该能够轻松地提取它。 – emboss 2012-05-02 22:13:43

1

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

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

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

+0

我有相同的要求,我有asn1Object。从那里我需要解析数据并获得所需的数据,请你提供代码? – 2013-12-05 09:50:11

+0

什么是CustomTreeNode? – 2016-02-24 13:29:22

4

只要使用“真”来打印值

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(); 
+0

仅供参考:具有两个参数的dumpAsString在旧版本的bouncycastle版本中不可用。 – kukudas 2015-01-28 12:53:17