studio significa que not found for conexion certification certificado android ssl https

android - conexion - trust anchor for certification path not found que significa



Cómo habilitar la compatibilidad con TLS 1.2 en una aplicación de Android(que se ejecuta en Android 4.1 JB) (7)

2 formas de habilitar TLSv1.1 y TLSv1.2:

  1. use esta guía: http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/
  2. use esta clase https://github.com/erickok/transdroid/blob/master/app/src/main/java/org/transdroid/daemon/util/TlsSniSocketFactory.java
    schemeRegistry.register(new Scheme("https", new TlsSniSocketFactory(), port));

Según los documentos en Android para SSLSocket y SSLContext , los protocolos TLS v1.1 y v1.2 son compatibles con el nivel de API 16+, pero no están habilitados de forma predeterminada. http://developer.android.com/reference/javax/net/ssl/SSLSocket.html http://developer.android.com/reference/javax/net/ssl/SSLContext.html

¿Cómo lo habilito en un dispositivo con Android 4.1 o posterior (pero por debajo de 5.0)?

Intenté crear un SSLSocketFactory personalizado que habilita todos los protocolos compatibles cuando se crean Socket y luego uso mi implementación personalizada como:

HttpsURLConnection.setDefaultSSLSocketFactory (nuevo MySSLSocketFactory ());

public class MySSLSocketFactory extends SSLSocketFactory { private SSLContext sc; private SSLSocketFactory ssf; public MySSLSocketFactory() { try { sc = SSLContext.getInstance("TLS"); sc.init(null, null, null); ssf = sc.getSocketFactory(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { SSLSocket ss = (SSLSocket) ssf.createSocket(s, host, port, autoClose); ss.setEnabledProtocols(ss.getSupportedProtocols()); ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); return ss; } @Override public String[] getDefaultCipherSuites() { return ssf.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return ssf.getSupportedCipherSuites(); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { SSLSocket ss = (SSLSocket) ssf.createSocket(host, port); ss.setEnabledProtocols(ss.getSupportedProtocols()); ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); return ss; } @Override public Socket createSocket(InetAddress host, int port) throws IOException { SSLSocket ss = (SSLSocket) ssf.createSocket(host, port); ss.setEnabledProtocols(ss.getSupportedProtocols()); ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); return ss; } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { SSLSocket ss = (SSLSocket) ssf.createSocket(host, port, localHost, localPort); ss.setEnabledProtocols(ss.getSupportedProtocols()); ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); return ss; } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { SSLSocket ss = (SSLSocket) ssf.createSocket(address, port, localAddress, localPort); ss.setEnabledProtocols(ss.getSupportedProtocols()); ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); return ss; } }

Pero aún da una excepción al intentar establecer una conexión con un servidor en el que Solo TLS 1.2 está habilitado.

Aquí está la excepción que obtengo:

03-09 09: 21: 38.427: W / System.err (2496): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake abortado: ssl = 0xb7fa0620: Fallo en la biblioteca SSL, generalmente un protocolo error

03-09 09: 21: 38.427: W / System.err (2496): error: 14077410: Rutinas SSL: SSL23_GET_SERVER_HELLO: error de apretón de manos de alerta sslv3 (externo / openssl / ssl / s23_clnt.c: 741 0xa90e6990: 0x00000000)


@ Inherentemente curioso: gracias por publicar esto. Ya casi está allí: debe agregar dos parámetros más al método SSLContext.init ().

class MyHttpRequestTask extends AsyncTask<String,Integer,String> { @Override protected String doInBackground(String... params) { String my_url = params[0]; try { URL url = new URL(my_url); HttpsURLConnection httpURLConnection = (HttpsURLConnection) url.openConnection(); httpURLConnection.setSSLSocketFactory(new MyFactory()); // setting the Request Method Type httpURLConnection.setRequestMethod("GET"); // adding the headers for request httpURLConnection.setRequestProperty("Content-Type", "application/json"); String result = readStream(httpURLConnection.getInputStream()); Log.e("My Networking", "We have data" + result.toString()); }catch (Exception e){ e.printStackTrace(); Log.e("My Networking", "Oh no, error occurred " + e.toString()); } return null; } private static String readStream(InputStream is) throws IOException { final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("US-ASCII"))); StringBuilder total = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { total.append(line); } if (reader != null) { reader.close(); } return total.toString(); } }

comenzará a funcionar. Nuevamente muchas gracias por publicar esto. Resolví este / mi problema con su código.


Agregue la biblioteca play-services-safetynet en android build.gradle :

TrustManager[] trustManagers = new TrustManager[] { new TrustManagerManipulator() }; sc.init(null, trustManagers, new SecureRandom());

y agregue este código a su MainApplication.java :

class MyFactory extends SSLSocketFactory { private javax.net.ssl.SSLSocketFactory internalSSLSocketFactory; public MyFactory() throws KeyManagementException, NoSuchAlgorithmException { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, null, null); internalSSLSocketFactory = context.getSocketFactory(); } @Override public String[] getDefaultCipherSuites() { return internalSSLSocketFactory.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return internalSSLSocketFactory.getSupportedCipherSuites(); } @Override public Socket createSocket() throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket()); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); } private Socket enableTLSOnSocket(Socket socket) { if(socket != null && (socket instanceof SSLSocket)) { ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); } return socket; } }


Como dijo el OP, los protocolos TLS v1.1 y v1.2 son compatibles con el nivel API 16+, pero no están habilitados de forma predeterminada, solo tenemos que habilitarlo.

El ejemplo aquí usa HttpsUrlConnection , no HttpUrlConnection . Siga https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ , podemos crear una fábrica

new MyHttpRequestTask().execute(myUrl);

((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); biblioteca de redes que utilice, asegúrese de ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); se llama por lo que el Socket ha habilitado los protocolos TLS.

Ahora, puede usar eso en HttpsUrlConnection

minSdkVersion 16

Por ejemplo

implementation ''com.google.android.gms:play-services-safetynet:+''

Además, recuerde minSdkVersion en build.gradle a 16

@Override public void onCreate() { super.onCreate(); upgradeSecurityProvider(); SoLoader.init(this, /* native exopackage */ false); } private void upgradeSecurityProvider() { ProviderInstaller.installIfNeededAsync(this, new ProviderInstallListener() { @Override public void onProviderInstalled() { } @Override public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) { // GooglePlayServicesUtil.showErrorNotification(errorCode, MainApplication.this); GoogleApiAvailability.getInstance().showErrorNotification(MainApplication.this, errorCode); } }); }


Deberías usar

SSLContext.getInstance("TLSv1.2");

para la versión específica del protocolo.

La segunda excepción ocurrió porque socketFactory predeterminado utilizó el protocolo SSLv3 de respaldo para fallas.

Puede usar NoSSLFactory de la respuesta principal aquí para su supresión ¿Cómo deshabilitar SSLv3 en Android para HttpsUrlConnection?

También debe iniciar SSLContext con todos sus certificados (clientes y de confianza si los necesita)

Pero todo eso es inútil sin usar

ProviderInstaller.installIfNeeded(getContext())

Aquí hay más información con el escenario de uso adecuado https://developer.android.com/training/articles/security-gms-provider.html

Espero eso ayude.


Resolví este problema siguiendo las indicaciones proporcionadas en el artículo http://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ con pequeños cambios.

SSLContext context = SSLContext.getInstance("TLS"); context.init(null, null, null); SSLSocketFactory noSSLv3Factory = null; if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory()); } else { noSSLv3Factory = sslContext.getSocketFactory(); } connection.setSSLSocketFactory(noSSLv3Factory);

Este es el código del TLSSocketFactory personalizado:

public static class TLSSocketFactory extends SSLSocketFactory { private SSLSocketFactory internalSSLSocketFactory; public TLSSocketFactory(SSLSocketFactory delegate) throws KeyManagementException, NoSuchAlgorithmException { internalSSLSocketFactory = delegate; } @Override public String[] getDefaultCipherSuites() { return internalSSLSocketFactory.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return internalSSLSocketFactory.getSupportedCipherSuites(); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); } /* * Utility methods */ private static Socket enableTLSOnSocket(Socket socket) { if (socket != null && (socket instanceof SSLSocket) && isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn''t provide there TLS version ((SSLSocket) socket).setEnabledProtocols(new String[]{TLS_v1_1, TLS_v1_2}); } return socket; } private static boolean isTLSServerEnabled(SSLSocket sslSocket) { System.out.println("__prova__ :: " + sslSocket.getSupportedProtocols().toString()); for (String protocol : sslSocket.getSupportedProtocols()) { if (protocol.equals(TLS_v1_1) || protocol.equals(TLS_v1_2)) { return true; } } return false; } }

Editar: Gracias a ademar111190 por la implementación de kotlin ( link )

class TLSSocketFactory constructor( private val internalSSLSocketFactory: SSLSocketFactory ) : SSLSocketFactory() { private val protocols = arrayOf("TLSv1.2", "TLSv1.1") override fun getDefaultCipherSuites(): Array<String> = internalSSLSocketFactory.defaultCipherSuites override fun getSupportedCipherSuites(): Array<String> = internalSSLSocketFactory.supportedCipherSuites override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean) = enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)) override fun createSocket(host: String, port: Int) = enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)) override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int) = enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)) override fun createSocket(host: InetAddress, port: Int) = enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)) override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int) = enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)) private fun enableTLSOnSocket(socket: Socket?) = socket?.apply { if (this is SSLSocket && isTLSServerEnabled(this)) { enabledProtocols = protocols } } private fun isTLSServerEnabled(sslSocket: SSLSocket) = sslSocket.supportedProtocols.any { it in protocols } }


Tengo algunas adiciones a las respuestas mencionadas anteriormente. De hecho, es un truco mencionado por Jesse Wilson de okhttp, here . De acuerdo con este truco, tuve que cambiar el nombre de mi variable SSLSocketFactory a

private SSLSocketFactory delegate;

Esta es mi clase TLSSocketFactory

public class TLSSocketFactory extends SSLSocketFactory { private SSLSocketFactory delegate; public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, null, null); delegate = context.getSocketFactory(); } @Override public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } @Override public Socket createSocket() throws IOException { return enableTLSOnSocket(delegate.createSocket()); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return enableTLSOnSocket(delegate.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enableTLSOnSocket(delegate.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort)); } private Socket enableTLSOnSocket(Socket socket) { if(socket != null && (socket instanceof SSLSocket)) { ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); } return socket; } }

y así es como lo usé con okhttp y retrofit

OkHttpClient client=new OkHttpClient(); try { client = new OkHttpClient.Builder() .sslSocketFactory(new TLSSocketFactory()) .build(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } Retrofit retrofit = new Retrofit.Builder() .baseUrl(URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();