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
Merci Hugo, plus une réponse satisfaisante. – preem
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. –
@ 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é. –