2011-10-19 18 views
11

Por el momento estoy escribiendo una biblioteca java para acceder a la API REST de pointhq.com.necesita ayuda para entender cadenas de certificados

Durante el desarrollo de un cliente Android me di cuenta de que el certificado SSL no es aceptado por defecto así que escribí una costumbre TrustManager y añadí el certificado pointhq.com como se explica en este post: Trusting all certificates using HttpClient over HTTPS

El uso de este TrustManager y mi importados bks file Obtengo el siguiente error al intentar conectar: ​​IssuerName(CN=GeoTrust Global CA, O=GeoTrust Inc., C=US) does not match SubjectName(CN=RapidSSL CA, O="GeoTrust, Inc.", C=US) of signing certificate.

Entonces, ¿qué hice mal? Importé los certificados pointhq.com, rapidssl.com, geotrust.com. Pero nada cambió. ¿Hay algún tipo de clasificación de certificados que deba conocer? ¿Me falta un certificado raíz?

EDIT: Aquí está la lista de certificados importados:

Tipo: BKS Proveedor: BC entradas: 3

entrada Alias: geotrust mundial ca Fecha de creación: 19.10.2011 15:44: 35 MESZ Tipo: Trusted Certificado Certificados: 1

Certificate 1 of 1 
Version: 3 
Subject: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US 
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US 
Serial Number: 0002 3456 
Valid From: 21.05.2002 06:00:00 
Valid Until: 21.05.2022 06:00:00 
Public Key: RSA (2.048 bits) 
Signature Algorithm: SHA1withRSA 
SHA-1 Fingerprint: DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12 
MD5 Fingerprint: F7:75:AB:29:FB:51:4E:B7:77:5E:FF:05:3C:99:8E:F5 

entrada Alias: pointhq.com (rapidssl bis) Fecha de creación: 29.09.2011 18:55:12 MESZ Tipo: Trusted Certificado Certificados: 1

Certificate 1 of 1 
Version: 3 
Subject: CN=pointhq.com, OU=Domain Control Validated - RapidSSL(R), OU=See www.rapidssl.com/resources/cps (c)11, OU=GT70151377, O=pointhq.com, C=GB, SERIALNUMBER=8Dvj7qRSYLjGZiX2tHocE2FDaqAp8RwO 
Issuer: CN=RapidSSL CA, O="GeoTrust, Inc.", C=US 
Serial Number: 8971 
Valid From: 31.01.2011 13:20:09 
Valid Until: 03.02.2013 09:15:38 
Public Key: RSA (2.048 bits) 
Signature Algorithm: SHA1withRSA 
SHA-1 Fingerprint: BB:04:D0:3E:1A:36:02:F7:C3:8C:85:99:1D:67:2A:6B:CF:C1:BC:C5 
MD5 Fingerprint: 21:9D:DF:72:E6:4A:33:47:E1:BA:D6:52:86:1E:59:B4 

entrada Alias: rapidssl ca (GEOTRUST ca global) Fecha de creación: 29.09.2011 18:54: 49 MESZ Tipo: Trusted Certificado Certificados: 1

Certificate 1 of 1 
Version: 3 
Subject: CN=RapidSSL CA, O="GeoTrust, Inc.", C=US 
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US 
Serial Number: 0002 36D1 
Valid From: 19.02.2010 23:45:05 
Valid Until: 18.02.2020 23:45:05 
Public Key: RSA (2.048 bits) 
Signature Algorithm: SHA1withRSA 
SHA-1 Fingerprint: C0:39:A3:26:9E:E4:B8:E8:2D:00:C5:3F:A7:97:B5:A1:9E:83:6F:47 
MD5 Fingerprint: 1B:EE:28:5E:8F:F8:08:5F:79:CC:60:8B:92:99:A4:53 

ahora escribió una aplicación de prueba SSL. Los resultados son confusos Como puede ver en las capturas de pantalla adjuntas, a veces se acepta la conexión SSL y otras veces no. Incluso si es el mismo sitio al que me estoy conectando.

https://ssltest12.bbtest.net/ es el sitio de demostración para el certificado RapidSSL I qué usar. Como puede ver en la captura de pantalla de Android 2.1, la primera conexión no es aceptada, pero la segunda prueba funciona perfectamente bien, mientras que la última no funciona de nuevo. ¿Cómo puede suceder eso?

BTW: ¡Desde Android 2.3.3 se acepta el certificado RapidSSL sin ningún código personalizado!

Scrennshots:

+0

¿Puede también enviar los certificados que ha importado? Parece que los nombres no coinciden. –

+0

Su configuración parece perder el certificado intermedio RapidSSL en su cadena de certificados. ¿Hay alguna manera de forzar su cadena en TrustManager? – kroonwijk

+0

@kroonwijk ¿cuál debería estar faltando? ¿Qué quiere decir con "forzar su cadena"? Pensé que tal vez el orden de los certificados es incorrecto en mi archivo BKS? Trataré de reorganizarlos ... –

Respuesta

6

Sí, el orden de los certificados en cuestión cadena. Básicamente, usted desea que los certificados sean enviados desde el suyo a CA. Los navegadores lo hacen por usted, pero Java no lo hace.Tuve el problema con los certificados no ordenadas en cadena y terminé escribiendo una implementación sencilla de X509TrustManager con:

public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException { 
    if ((certificates != null) && LOG.isDebugEnabled()) { 
     LOG.debug("Server certificate chain:"); 
     for (int i = 0; i < certificates.length; i++) { 
      LOG.debug("X509Certificate[" + i + "]=" + certificates[i]); 
     } 
    } 
    if ((certificates != null) && (certificates.length == 1)) { 
     certificates[0].checkValidity(); 
    } else { 
     List<X509Certificate> certs = new ArrayList<X509Certificate>(); 
     certs.addAll(Arrays.asList(certificates)); 
     X509Certificate certChain = certs.get(0); 
     certs.remove(certChain); 
     LinkedList<X509Certificate> chainList= new LinkedList<X509Certificate>(); 
     chainList.add(certChain); 
     Principal certIssuer = certChain.getIssuerDN(); 
     Principal certSubject = certChain.getSubjectDN(); 
     while(!certs.isEmpty()){ 
      List<X509Certificate> tempcerts = new ArrayList<X509Certificate>(); 
      tempcerts.addAll(certs); 
      for (X509Certificate cert : tempcerts){ 
       if(cert.getIssuerDN().equals(certSubject)){ 
        chainList.addFirst(cert); 
        certSubject = cert.getSubjectDN(); 
        certs.remove(cert); 
        continue; 
       } 

       if(cert.getSubjectDN().equals(certIssuer)){ 
        chainList.addLast(cert); 
        certIssuer = cert.getIssuerDN(); 
        certs.remove(cert); 
        continue; 
       } 
      } 
     } 
    standardTrustManager.checkServerTrusted(chainList.toArray(new X509Certificate[]{}),authType); 

    } 
} 

Aviso el ciclo de pedidos "mientras que".

+1

Ten cuidado. Esto termina en un bucle ocupado, si tiene alguna mierda en la cadena suministrada (como una versión anterior del certificado del servidor). Sí, me encontré con eso ... Los navegadores y demás simplemente ignoraron el certificado adicional. –

+0

Por lo que sé, 'certificados [0] .checkValidity();' no es suficiente para evitar un ataque de hombre en el medio, ya que solo verifica el intervalo de tiempo en que el certificado es válido. Supongo que la verificación también debe hacerse usando 'standardTrustManager', en la rama' if ((certificates! = Null) && (certificates.length == 1)) {'. –

Cuestiones relacionadas