2010-03-09 17 views
14

Estoy tratando de leer una extensión personalizada de un certificado digital. Sé que el valor es un GeneralString codificado en DER. ¿Hay alguna manera fácil de decodificarlo correctamente y obtener Java String? Intenté lo siguiente, pero 's' incluye algunos de los metadatos de codificación como caracteres basura al comienzo de la cadena.¿Cómo decodifico una cadena codificada DER en Java?

byte[] ext = cert.getExtensionValue("1.2.3.4"); 
String s= new String(ext); 
System.out.println(s); 

¿Existe una manera rápida y fácil de hacerlo? ¿O realmente necesito usar alguna biblioteca completa de ASN.1?

Gracias!

Respuesta

6

BouncyCastle es (entre todo lo demás):

Una biblioteca para leer y escribir objetos ASN.1 codificados.

9

Esto resulta ser bastante sencillo con BouncyCastle:

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException 
{ 
    String decoded = null; 
    byte[] extensionValue = X509Certificate.getExtensionValue(oid); 

    if (extensionValue != null) 
    { 
     DERObject derObject = toDERObject(extensionValue); 
     if (derObject instanceof DEROctetString) 
     { 
      DEROctetString derOctetString = (DEROctetString) derObject; 

      derObject = toDERObject(derOctetString.getOctets()); 
      if (derObject instanceof DERUTF8String) 
      { 
       DERUTF8String s = DERUTF8String.getInstance(derObject); 
       decoded = s.getString(); 
      } 

     } 
    } 
    return decoded; 
} 

private DERObject toDERObject(byte[] data) throws IOException 
{ 
    ByteArrayInputStream inStream = new ByteArrayInputStream(data); 
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream); 

    return asnInputStream.readObject(); 
} 
+1

Hola parece DERObject ya no se utiliza. Cualquier posibilidad de que puedas actualizar tu código de ejemplo. Creo que ahora tiene que usar org.bouncycastle.sasn1.Asn1Object en su lugar, pero todavía no he podido hacer que funcione. – user1513388

+0

@ user1513388 Lo siento, esto fue hace más de 2 años. Ni siquiera estoy usando Java en algo ahora mismo, así que no estoy seguro si/cuándo podría intentarlo de nuevo. – Ragesh

+0

¡De acuerdo, gracias por responder! – user1513388

10

utilización de las instrucciones contenidas en la página siguiente he hecho algunos cambios y el código trabajaron bien conmigo.

Trasladar desde versiones anteriores BC a 1,47 y más tarde - La legión del Castillo Hinchable http://www.bouncycastle.org/wiki/display/JA1/Porting+from+earlier+BC+releases+to+1.47+and+later

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException 
{ 
    String decoded = null; 
    byte[] extensionValue = X509Certificate.getExtensionValue(oid); 

    if (extensionValue != null) 
    { 
     ASN1Primitive derObject = toDERObject(extensionValue); 
     if (derObject instanceof DEROctetString) 
     { 
      DEROctetString derOctetString = (DEROctetString) derObject; 

      derObject = toDERObject(derOctetString.getOctets()); 
      if (derObject instanceof ASN1String) 
      { 
       ASN1String s = (ASN1String)derObject; 
       decoded = s.getString(); 
      } 

     } 
    } 
    return decoded; 
} 

/** 
* From http://stackoverflow.com/questions/2409618/how-do-i-decode-a-der-encoded-string-in-java 
*/ 
private ASN1Primitive toDERObject(byte[] data) throws IOException 
{ 
    ByteArrayInputStream inStream = new ByteArrayInputStream(data); 
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream); 

    return asnInputStream.readObject(); 
} 
1

JcaX509ExtensionUtils hace lo que las respuestas anteriores hacen de una manera mucho más sencilla.

X509Certificate certificate; 
byte[] encodedExtensionValue = certificate.getExtensionValue(oid); 
if (encodedExtensionValue != null) { 
    ASN1Primitive extensionValue = JcaX509ExtensionUtils 
      .parseExtensionValue(encodedExtensionValue); 
    String values = extensionValue.toString();   
} 
Cuestiones relacionadas