2017-06-12 2 views
1

Je veux faire une structure ASN.1 personnalisée, ce qui consiste en 3 PrintableString et 1 OctetString. J'utilise le framework BouncyCastle pour travailler avec ça. Donc j'ai mis dans ma classe les paramètres nécessaires, et maintenant je dois retourner cette structure au format ASN.1, puis l'encoder avec Base64 (son paramètre est byte []), puis au format PEM.Exporter le format ASN.1, puis encoder avec Base64 JAVA

Donc, ma question est, quel type d'objet dois-je retourner à partir de la méthode getASN1format()?

Mon code:

import org.bouncycastle.asn1.*; 
import java.io.IOException; 

public class ASN1Handshake1 implements ASN1Encodable { 
    private DERPrintableString A, B, ID_PASS; 
    private ASN1OctetString ID_K; 

    public ASN1Handshake1(String A, String B, String ID_K, String ID_PASS, TTP TTPs) throws IOException { 
     this.A = new DERPrintableString(A); 
     this.B = new DERPrintableString(B); 
     this.ID_K = new DEROctetString(ID_K.getBytes()); 
     this.ID_PASS = new DERPrintableString(ID_PASS); 
    } 

    public ?? getASN1format(){ 
     //TODO 
    } 

    @Override 
    public ASN1Primitive toASN1Primitive() { 
     return null; 
    } 
} 

Répondre

1

J'utilise Bouncy Castle 1,57 (bcprov-jdk15on) pour ce code.

tout d'abord, gardez à l'esprit que ASN.1 est pas un format en soi, c'est un description language qui définit une structure et PEM is a format that uses base 64. De nombreuses normes de cryptographie utilisent ASN.1 pour définir leurs structures de données, et PEM ou DER (Distinguished Encoding Rules) pour sérialiser ces structures. Donc, si vous voulez obtenir la structure ASN.1 et la formater en base64, vous pouvez faire comme ci-dessous. Vous n'avez pas besoin d'une méthode getASN1format, utilisez simplement celles qui existent déjà.

Les champs ne peuvent pas être "détachés" dans la structure ASN.1. J'ai donc décidé de les mettre dans une séquence (en utilisant la classe org.bouncycastle.asn1.DERSequence), ce qui est le meilleur choix pour stocker les champs d'une structure. Je les mets dans l'ordre où ils sont déclarés, mais bien sûr vous pouvez choisir n'importe quelle commande que vous voulez.

J'ai également changé les noms de variables à suivre Java's code conventions (les noms commencent par des minuscules). Ainsi, le code de classe est:

import org.bouncycastle.asn1.ASN1Encodable; 
import org.bouncycastle.asn1.ASN1Object; 
import org.bouncycastle.asn1.ASN1OctetString; 
import org.bouncycastle.asn1.ASN1Primitive; 
import org.bouncycastle.asn1.ASN1Sequence; 
import org.bouncycastle.asn1.DEROctetString; 
import org.bouncycastle.asn1.DERPrintableString; 
import org.bouncycastle.asn1.DERSequence; 

public class ASN1Handshake1 extends ASN1Object { 

    private DERPrintableString a, b, idPass; 

    private ASN1OctetString idK; 

    // removed TTPs parameter (it wasn't using it) 
    public ASN1Handshake1(String a, String b, String idK, String idPass) { 
     this.a = new DERPrintableString(a); 
     this.b = new DERPrintableString(b); 
     this.idK = new DEROctetString(idK.getBytes()); 
     this.idPass = new DERPrintableString(idPass); 
    } 

    // returns a DERSequence containing all the fields 
    @Override 
    public ASN1Primitive toASN1Primitive() { 
     ASN1Encodable[] v = new ASN1Encodable[] { this.a, this.b, this.idK, this.idPass }; 
     return new DERSequence(v); 
    } 
} 

Pour créer un objet de poignée de main et le convertir en base64 (le code ci-dessous ne traite pas des exceptions, il faut donc ajouter le bloc try/catch en conséquence):

Affichera la structure de poignée de main au format base64:

MBUTAWETAWIEBElEX0sTB0lEX1BBU1M =

S'il vous plaît noter que ce n'est pas un PEM complet (avec des en-têtes comme -----BEGIN CERTIFICATE-----) parce que votre structure personnalisée n'est pas une norme prédéfinie. Donc, vous devrez rester avec cette chaîne générique base64.

Pour vérifier que la chaîne base64 contient l'ASN.1 séquence, il suffit de faire:

// read from base64 String 
ASN1Sequence seq = (ASN1Sequence) DERSequence.fromByteArray(Base64.decode(base64String.getBytes())); 
int n = seq.size(); 
for (int i = 0; i < n; i++) { 
    ASN1Encodable obj = seq.getObjectAt(i); 
    if (obj instanceof DEROctetString) { 
     System.out.println(new String(((DEROctetString) obj).getOctets())); 
    } else { 
     System.out.println(obj); 
    } 
} 

La sortie est:

un
b
ID_K
ID_PASS

+1

Merci Hugo, plus une réponse satisfaisante. – preem

+0

Votre exemple ne le montre pas, mais en général PEM est base64 _avec des sauts de ligne ajoutés toutes les 64 (ou plus) caractères_ plus les lignes tiret-BEGIN/END-typename. –

+0

@ dave_thompson_085 Les paramètres BEGIN/END correspondent à des types définis, tels que certificat, CSR, clés, etc. Mais dans ce cas, c'est une structure personnalisée avec un format "non-standard". Je ne suis pas sûr si l'on peut simplement créer un nouveau type ou s'il est standardisé. –