Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Hacer una conexión HTTPS mediante URL.openConnection ()

Estoy intentando hacer una conexión de HTTPS a un servidor que tiene un certificado fijado para expirar en abril de 2013 y utiliza GlobalSign como el certificado de la raíz.

HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); // urlConnection.setSSLSocketFactory(sslSocketFactory); urlConnection.setDoOutput(true); urlConnection.setChunkedStreamingMode(0); // Send the POST data OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); out.write(postParamString.toString().getBytes("UTF8")); // Read the reply InputStream in = urlConnection.getInputStream(); 

Tal como está, esto lanza javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. Cuando se llama getOutputStream() .

Este mismo sitio y certificado son válidos en el navegador web HTC y en los navegadores de escritorio. Cuando utilizo el mismo código para acceder a Google funciona (pero luego se queja de un error 404). Varios puestos en StackOverflow implican que debe "sólo funciona" y otros dicen que para configurar su propia tienda de claves (o desactivar toda la validación de HTTPS!) Supongo que la diferencia en el comportamiento es a diferentes almacenes de la clave raíz en uso (¿Puede alguien aclarar esto ?).

Ahora he intentado crear un almacén de la llave usando el castillo bouncy pero no puedo conseguir esto para cargar en mi dispositivo.

Después de exportar el certificado de Firefox, creo un almacén de claves usando:

 keytool.exe -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -keystore res\raw\keystore 

Esto se carga y se utiliza en la aplicación utilizando:

 InputStream stream = context.getResources().openRawResource(R.raw.keystore); // BKS seems to be the default but we want to be explicit KeyStore ks = KeyStore.getInstance("BKS"); ks.load(stream, "www.onlinescoutmanager.co.uk".toCharArray()); stream.close(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SSLContext context2 = SSLContext.getInstance("TLS"); context2.init(null, new TrustManager[] { defaultTrustManager }, null); sslSocketFactory = context2.getSocketFactory(); 

Esto está fallando con java.io.IOException: Wrong version of key store. Cuando keystore.Load() se llama.

He asegurado que estoy pasando -storetype BKS , usé una contraseña de keystore de <= 7 caracteres , añadí los certs de CA al almacén de claves y usando ambos Bouncy Castle versión 1.45 y 1.47 para crear el almacén de claves sin cambio en el error reportado mensaje.

Mi entorno es Eclipse Juno 4.2.1 con JRE 1.7u9b5 que se ejecuta en Windows 8. El dispositivo que estoy probando es una sensación HTC corriendo Android 2.3. La aplicación tiene una versión SDK mínima de 7 y un objetivo de 15.

Si alguien puede explicar cómo crear un almacén de claves BKS válido en Windows 8 o cómo puedo conseguir que Java utilice el mismo almacén de claves que el navegador (o el sistema?) Que sería apreciado.

Puede descargar todo el proyecto tal como estaba en el momento de escribir, y el almacén de claves generado si es necesario.

  • Buenas prácticas: ¿Cómo manejar las contraseñas del keystore en android / java?
  • Hash de clave de facebook, confusión de keystore android
  • Android Studio - Keystore fue manipulado o la contraseña fue incorrecta
  • Keystore y alias - ¿hay un uso a varios alias?
  • Android: Perdí mi tienda de la llave del androide, qué debo hacer?
  • Versión errónea keystore al hacer llamadas https
  • ¿Cómo crear una llave RSA keystore Android con una validez infinita?
  • Configurar Eclipse para usar el almacén de claves firmado
  • 2 Solutions collect form web for “Hacer una conexión HTTPS mediante URL.openConnection ()”

    Bouncy Castle 1.47 utiliza cabecera de versión diferente. ¿Puedes probar la versión 1.46 , debería funcionar.

     keytool -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -storepass osmosm -keystore C:/keystore -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-ext-jdk15on-1.46.jar 

    Gracias a varias personas por sus consejos sobre esto, hay varias cosas que todo lo necesario para ser correcto para que funcione.

    1. Si el certificado del sitio HTTPS está firmado por un certificado raíz de confianza, funcionará fuera de la caja sin un SSLSocketFactory personalizado. Los certificados de raíz de confianza pueden ser diferentes a los usados ​​por un navegador, así que no asuma que si funciona en el navegador web de Android, funcionará en su aplicación.
      Si no es un certificado raíz de confianza y obtiene excepciones como javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate signature. , Entonces necesita crear y cargar un almacén de claves como se muestra a continuación.

    2. El almacén de claves debe generarse utilizando el proveedor Bouncy Castle ( 1 ) especificando -storetype bks en la línea de comandos keytool .
      Si Bouncy Castle no se instala correctamente, esto fallará con varias excepciones, incluyendo java.security.KeyStoreException: BKS not found . Si no se crea el almacén de claves con el proveedor Bouncy Castle, puede obtener la java.io.IOException: Wrong version of key store. Excepción, causando confusión con el caso siguiente.

    3. Necesita usar una versión apropiada ( 1 , 2 , 3 ) del proveedor de Bouncy Castle. En la mayoría de los casos, esto parece ser la versión 1.46 .
      Esto se puede poner en la carpeta lib/ext/ JRE y el nombre de la clase agregado a lib/security/java.security , o se especifica directamente en la línea de comandos a keytool . Si se trata de una versión incompatible (o tipo de tienda) obtendrá excepciones a lo largo de las líneas de java.io.IOException: Wrong version of key store. de nuevo.

    4. Debe incluir todos los intermediarios y el certificado raíz. Si faltan alguno, obtendrá una javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. excepción.

    5. La cadena de certificados DEBE estar en orden para que sean validados correctamente. Si no lo son, obtendrás javax.net.ssl.SSLHandshakeException: org.bouncycastle.jce.exception.ExtCertPathValidatorException: IssuerName(CN=XYZ) does not match SubjectName(CN=ABC) of signing certificate. O de nuevo, un genérico javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. No he encontrado una forma de ordenarlos en el almacén de claves, así que recurrí a hacerlo en código en tiempo de ejecución .

    Algunas personas han sugerido que usar una contraseña de keystore de más de 7 caracteres también hará que falle, pero eso no es lo que he encontrado.

    Creo que esto cubre cada fallo que encontré, pero siéntase libre de expandir y añadir linsk a preguntas relacionadas.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.