web-dev-qa-db-fra.com

Analyser les données binaires ASN.1 avec Java

J'ai des objets de données binaires ASN.1 que je dois analyser dans mon Java. Je veux juste la structure et les données ASN.1 telles qu'elles sont analysées par exemple par le visualiseur BER:

ASN.1 structure as shown in BER viewer

L'analyseur ASN.1 de BouncyCastle n'est pas en mesure d'analyser cette structure (renvoie uniquement le type de données binaires spécifique à l'application).

Quelle bibliothèque ASN.1 puis-je utiliser pour obtenir un tel résultat? Quelqu'un a-t-il un exemple de code qui montre comment analyser un objet ASN.1?

BTW: J'ai également essayé plusieurs compilateurs ASN.1 gratuits Java mais aucun n'est capable de générer un Java code donné peut être la spécification ASN.1).

20
Robert

Je dois me corriger - il est possible de lire les données en utilisant l'analyseur ASN.1 inclus dans BouncyCastle - mais le processus n'est pas si simple.

Si vous souhaitez uniquement imprimer les données contenues dans une structure ASN.1, je vous recommande d'utiliser la classe org.bouncycastle.asn1.util.ASN1Dump . Il peut être utilisé par l'extrait de code simple suivant:

ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(data));
ASN1Primitive obj = bIn.readObject();
System.out.println(ASN1Dump.dumpAsString(obj));

Il imprime la structure mais pas les données - mais en copiant l'ASN1Dump dans une propre classe et en le modifiant pour imprimer par exemple OCTET_STRINGS cela peut être fait facilement.

En outre, le code dans ASN1Dump montre pour analyser les structures ASN.1. Pour l'exemple, les données utilisées dans ma question peuvent être analysées un niveau plus en profondeur à l'aide du code suivant:

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

Utilisez simplement "true" pour imprimer les valeurs

    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();
4
test1

Il ne ressort pas clairement de votre question si vous disposez ou non de la spécification ASN.1 pour le BER que vous essayez d'analyser. Veuillez noter que sans la spécification ASN.1, vous ne pouvez donner un sens partiel aux données que si des TAGS EXPLICITES ont été utilisés dans la spécification ASN.1 à partir de laquelle elles ont été générées. Certains outils, comme celui de OSS Nokalva ont une bibliothèque (fichier jar) appelée JIAAPI qui vous permet de parcourir et de manipuler les encodages BER sans connaissance préalable de la spécification ASN.1.

Si vous avez la spécification ASN.1, tout compilateur ASN.1 Java devrait être capable de gérer cela.

Vous pouvez télécharger un essai gratuit des outils OSS ASN.1 pour Java from http://www.oss.com/asn1/products/asn1-download.html = pour voir si cela fonctionne mieux pour vous que pour les autres que vous avez essayés en vain.

3
Paul Thorpe

Si vous souhaitez simplement décoder les données codées BER, il existe de nombreux analyseurs. En avez-vous essayé? Il y en a même deux dans le Sun JDK - com.Sun.jmx.snmp.BerDecoder et com.Sun.jndi.ldap.BerDecoder .

2
Tom Anderson

J'ai besoin de pouvoir analyser tout type de données ASN.1 dans krypt. Bien que krypt soit un projet Ruby, vous voudrez peut-être jeter un œil à extension JRuby - le code de gestion de l'analyse/encodage ASN.1 est entièrement écrit en = Java et suffisamment modulaire pour une extraction facile.

J'ai également fait un version Java uniquement , mais il manque certaines des fonctionnalités de niveau supérieur de l'ancien. Mais comme c'est concis, c'est peut-être une bonne occasion de vous lancer.

2
emboss

J'utilise l'API bouncycastle pour imprimer la structure des chaînes, voici l'extrait de code:

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

En conséquence, c'est la structure d'impression, mais en chaîne d'octets, c'est la longueur d'impression au lieu de la valeur. Comment imprimer la valeur?

0
user2335004