Разбор двоичных данных ASN.1 с помощью Java

У меня есть двоичные объекты данных ASN.1, которые мне нужно проанализировать в моем проекте Java. Мне просто нужна структура и данные ASN.1, поскольку они анализируются, например, программой просмотра BER:

Структура ASN.1, показанная в средстве просмотра BER

Анализатор ASN.1 BouncyCastle не может анализировать эту структуру (возвращает только тип двоичных данных, специфичный для приложения).

Какую библиотеку ASN.1 можно использовать для получения такого результата? Есть ли у кого-нибудь пример кода, демонстрирующий, как анализировать объект ASN.1?

Кстати: я также пробовал несколько бесплатных компиляторов Java ASN.1, но ни один из них не может генерировать рабочий код Java, указанный в спецификации ASN.1.


person Robert    schedule 17.04.2012    source источник
comment
Вы просто хотите проанализировать поток данных BER или хотите реализовать определенную грамматику ASN.1?   -  person Tom Anderson    schedule 17.04.2012
comment
У меня есть грамматика ASN.1, но компиляторы ASN.1, которые я тестировал, не принимают ее. В любом случае я бы предпочел не ограничиваться теми объектами, для которых у меня есть грамматика.   -  person Robert    schedule 17.04.2012


Ответы (5)


Вынужден исправиться - данные можно считать с помощью парсера ASN.1, входящего в состав BouncyCastle, однако этот процесс не так прост.

Если вы хотите распечатать только данные, содержащиеся в структуре 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);
}
person Robert    schedule 11.05.2012

Просто используйте «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();
person test1    schedule 16.08.2014
comment
Для информации: dumpAsString с двумя параметрами недоступен в старых версиях bouncycastle. - person kukudas; 28.01.2015

Из вашего вопроса неясно, есть ли у вас спецификация ASN.1 для BER, который вы пытаетесь проанализировать. Обратите внимание, что без спецификации ASN.1 вы можете только частично понять данные, если EXPLICIT TAGS использовались в спецификации ASN.1, из которой они были сгенерированы. Некоторые инструменты, такие как инструмент из OSS Nokalva, имеют библиотеку (jar-файл) под названием JIAAPI, которая позволяет просматривать и манипулировать кодировками BER без предварительного знания спецификации ASN.1.

Если у вас есть спецификация ASN.1, любой компилятор Java ASN.1 должен справиться с этим.

Вы можете загрузить бесплатную пробную версию инструментов OSS ASN.1 для Java по адресу http://www.oss.com/asn1/products/asn1-download.html, чтобы узнать, работают ли для вас лучше, чем другие, которые вы безуспешно пробовали.

person Paul Thorpe    schedule 17.04.2012

Мне нужно иметь возможность анализировать любые данные ASN.1 в крипте. Хотя krypt — это проект Ruby, вы можете взглянуть на расширение JRuby — код для обработки синтаксического анализа/кодирования ASN.1 полностью написан на Java и достаточно модульен для простого извлечения.

Я также сделал версию только для Java, но в ней отсутствуют некоторые высокоуровневые функции первый. Но так как это лаконично, возможно, это хорошая возможность для начала.

person emboss    schedule 30.04.2012
comment
Ваш код выглядит красиво - к сожалению, я заметил, что мне нужен не только парсер/десериализатор ASN.1, но и сериализующая часть. - person Robert; 02.05.2012
comment
Спасибо! Я перестал продвигать версию только для Java, когда начал интегрировать ее в крипту, там вы также найдете биты сериализации. Весь пакет impl является автономным, поэтому он не будет смешиваться со спецификой JRuby — вы сможете легко его извлечь. - person emboss; 03.05.2012

Если вы просто хотите декодировать данные, закодированные в BER, существует множество синтаксических анализаторов. Вы пробовали? В Sun JDK их даже два — com.sun. jmx.snmp.BerDecoder и com.sun .jndi.ldap.BerDecoder.

person Tom Anderson    schedule 17.04.2012
comment
Примечание. Классы JDK в пакетах com.sun.* не являются общедоступными API и могут быть удалены/изменены в будущих выпусках. - person Puce; 17.04.2012
comment
@Tom: Я бы попробовал эти классы, но документация по этим классам так же хороша, как и документация по нескольким другим проектам ASN.1: почти не существует... - person Robert; 17.04.2012
comment
Документация не идеальна, но классы просты, и вы можете получить исходный код через OpenJDK. Я полагаю, что вы можете узнать все, что вам нужно знать, читая и экспериментируя. - person Tom Anderson; 17.04.2012