Ancla de confianza no encontrada para la conexión SSL de Android

Resuelto Chrispix asked hace 54 años • 23 respuestas

Estoy intentando conectarme a una caja IIS6 que ejecuta un certificado SSL de 256 bits de godaddy y aparece el error:

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

He estado tratando de determinar qué podría estar causando eso, pero ahora no tengo nada en blanco.

Así es como me estoy conectando:

HttpsURLConnection conn;              
conn = (HttpsURLConnection) (new URL(mURL)).openConnection();
conn.setConnectTimeout(20000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.connect();
String tempString = toString(conn.getInputStream());
Chrispix avatar Jan 01 '70 08:01 Chrispix
Aceptado

Al contrario de la respuesta aceptada, no necesita un administrador de confianza personalizado, ¡debe arreglar la configuración de su servidor!

Tuve el mismo problema al conectarme a un servidor Apache con un certificado dynadot/alphassl instalado incorrectamente. Me estoy conectando usando HttpsUrlConnection (Java/Android), lo que arrojaba:

javax.net.ssl.SSLHandshakeException: 
  java.security.cert.CertPathValidatorException: 
    Trust anchor for certification path not found.

El problema real es una mala configuración del servidor; pruébelo con http://www.digicert.com/help/ o similar, e incluso le indicará la solución:

"El certificado no está firmado por una autoridad confiable (comprobando con el almacén raíz de Mozilla). Si compró el certificado de una autoridad confiable, probablemente solo necesite instalar uno o más certificados intermedios . Comuníquese con su proveedor de certificados para obtener ayuda para hacer esto para su plataforma de servidor."

También puedes consultar el certificado con openssl:

openssl s_client -debug -connect www.thedomaintocheck.com:443

Probablemente verás:

Verify return code: 21 (unable to verify the first certificate)

y, anteriormente en la salida:

depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 OU = Domain Control Validated, CN = www.thedomaintocheck.com
verify error:num=21:unable to verify the first certificate`

La cadena de certificados solo contendrá 1 elemento (su certificado):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
  i:/O=AlphaSSL/CN=AlphaSSL CA - G2

... pero debe hacer referencia a las autoridades de firma en una cadena hacia una en la que Android confíe (Verisign, GlobalSign, etc.):

Certificate chain
 0 s:/OU=Domain Control Validated/CN=www.thedomaintocheck.com
   i:/O=AlphaSSL/CN=AlphaSSL CA - G2
 1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
   i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA

Las instrucciones (y los certificados intermedios) para configurar su servidor generalmente las proporciona la autoridad que emitió su certificado, por ejemplo: http://www.alphassl.com/support/install-root-certificate.html

Después de instalar los certificados intermedios proporcionados por el emisor de mi certificado, ahora no tengo errores al conectarme mediante HttpsUrlConnection.

Stevie avatar Apr 30 '2013 14:04 Stevie

¡La solución de @Chrispix es peligrosa! ¡Confiar en todos los certificados permite que cualquiera pueda realizar un ataque de hombre en el medio! ¡Simplemente envíe CUALQUIER certificado al cliente y lo aceptará!

Agregue sus certificados a un administrador de confianza personalizado como se describe en esta publicación: Confiar en todos los certificados usando HttpClient a través de HTTPS

Aunque es un poco más complejo establecer una conexión segura con un certificado personalizado, le brindará la seguridad de cifrado SSL deseada sin el peligro de un ataque de intermediario.

Matthias B avatar Oct 21 '2011 10:10 Matthias B

Puede confiar en un certificado particular en tiempo de ejecución.
Simplemente descárguelo del servidor, agregue recursos y cárguelo así usando ssl-utils-android :

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

En el ejemplo anterior utilicé OkHttpClientpero SSLContextpuedo utilizarlo con cualquier cliente en Java.

Si tiene alguna pregunta, sientase con libertad de preguntar. Soy el autor de esta pequeña biblioteca.

klimat avatar Oct 05 '2016 21:10 klimat