studio significa que not found for conexion certpathvalidatorexception certification certificado cert java android ssl

java - significa - ssl pinning



Android 4.4.2 SSL apretón de manos abortado (3)

El código funciona en mi emulador Genymotion Android 4.4.4 pero no en el dispositivo que estoy usando (4.4.2).

He intentado muchas soluciones alternativas de "confiar en todos los certificados" pero sin éxito (no creo que este sea el problema, ya que el certificado es AOK)

Creo que he identificado el cifrado (usando un rastro de wirehark desde mi escritorio); TLS 0x00 0x1E, que parece ser algo raro?

¿Alguna idea de cómo arreglarlo?

Aquí está mi código

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); CloseableHttpClient client = HttpClientBuilder.create().setSSLSocketFactory(sslsf).build(); String baseURL = "https://mysite.co.uk/api/"; HttpGetHC4 request = new HttpGetHC4(baseURL + "/authenticate?user=abcd&password=1234"); CloseableHttpResponse response = client.execute(request);

Y error;

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6abff398: Failure in SSL library, usually a protocol error error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684dfce0:0x00000000) at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:449) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:340) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:281) at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:124) at org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect(BasicHttpClientConnectionManager.java:322) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:373) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:225) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:178) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) at com.example.lee.printticket.Main$OrderAsyncTask.onPostExecute(Main.java:239) at com.example.lee.printticket.Main$OrderAsyncTask.onPostExecute(Main.java:189) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method) Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6abff398: Failure in SSL library, usually a protocol error error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684dfce0:0x00000000) at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method) at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:406) ... 25 more

EDITAR

Tratando de usar una técnica / biblioteca diferente;

RequestQueue queue = Volley.newRequestQueue(this); String url ="https://mysite.co.uk/api/authenticate?user=abcd&password=1234"; // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { // Display the first 500 characters of the response string. Log.d("response: ", response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.d("response: ", error.toString()); } }); // Add the request to the RequestQueue. queue.add(stringRequest);

Devoluciones;

D/response:: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6ad51be0: Failure in SSL library, usually a protocol error D/response:: error:140740B5:SSL routines:SSL23_CLIENT_HELLO:no ciphers available (external/openssl/ssl/s23_clnt.c:486 0x684dfce0:0x00000000)

O con el hack NoSSLv3SocketFactory de Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: Error en la biblioteca SSL, generalmente un error de protocolo ;

HttpStack stack = new HurlStack(null, new NoSSLv3SocketFactory()); RequestQueue queue = Volley.newRequestQueue(this, stack);

Devoluciones;

D/response:: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6ae51d30: Failure in SSL library, usually a protocol error D/response:: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684dfce0:0x00000000)


Android usa diferentes protocolos para las operaciones de red.

Configuración predeterminada para diferentes versiones de Android.

He encontrado solución para OkHttpClient.

Protocol Supported (API Levels) Enabled by default (API Levels) SSLv3 1–25 1–22 TLSv1 1+ 1+ TLSv1.1 16+ 20+ TLSv1.2 16+ 20+

Así que tenemos que cambiar el Protocolo para la conexión en Android VERSIÓN> = 16 y VERSIÓN <22.

Crear archivo java Tls12SocketFactory.java

/** * Enables TLS v1.2 when creating SSLSockets. * <p/> * For some reason, android supports TLS v1.2 from API 16, but enables it by * default only from API 20. * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html * @see SSLSocketFactory */ public class Tls12SocketFactory extends SSLSocketFactory { private static final String[] TLS_V12_ONLY = {"TLSv1.2"}; final SSLSocketFactory delegate; public Tls12SocketFactory(SSLSocketFactory base) { this.delegate = base; } @Override public String[] getDefaultCipherSuites() { return delegate.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return delegate.getSupportedCipherSuites(); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return patch(delegate.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return patch(delegate.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return patch(delegate.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return patch(delegate.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return patch(delegate.createSocket(address, port, localAddress, localPort)); } private Socket patch(Socket s) { if (s instanceof SSLSocket) { ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY); } return s; } }

Pon este método en algún lugar de tu código.

public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) { if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) { try { SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, null, null); client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory())); ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(TlsVersion.TLS_1_2).build(); List<ConnectionSpec> specs = new ArrayList<>(); specs.add(cs); specs.add(ConnectionSpec.COMPATIBLE_TLS); specs.add(ConnectionSpec.CLEARTEXT); client.connectionSpecs(specs); } catch (Exception exc) { Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc); } } return client; } public OkHttpClient getNewHttpClient() { OkHttpClient.Builder client = new OkHttpClient.Builder().followRedirects(true).followSslRedirects(true) .retryOnConnectionFailure(true).cache(null).connectTimeout(5, TimeUnit.SECONDS) .writeTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS); return enableTls12OnPreLollipop(client).build(); }

Crear una instancia de OkHttp como abajo:

private OkHttpClient getNewHttpClient() { OkHttpClient.Builder client = new OkHttpClient.Builder() .followRedirects(true) .followSslRedirects(true) .retryOnConnectionFailure(true) .cache(null) .connectTimeout(5, TimeUnit.SECONDS) .writeTimeout(5, TimeUnit.SECONDS) .readTimeout(5, TimeUnit.SECONDS); return enableTls12OnPreLollipop(client).build(); }

Usa el objeto cliente como este:

OkHttpClient client = getNewHttpClient(); Request.Builder requestBuilder = new Request.Builder(); URL url = new URL("YOUR_URL_LINK"); Request request = requestBuilder.url(url).build(); Call call = client.newCall(request); Response response = call.execute();

THANKS


Creo que el problema es SSL v3 basado en cadenas como esta, lo que sugiere que está intentando usar SSL v3: SSL23_GET_SERVER_HELLO: sslv3

SSL v3 se considera inseguro y, por lo tanto, está deshabilitado en la mayoría de los programas modernos (incluso en lugares donde de otra manera se esperaría que funcionara, muchas compañías simplemente lo han sacado de un tirón). También veo en el seguimiento de la pila que el código usa el cliente http de apache: org.apache.http.impl.client

Así que tienes que evitar que el cliente http de apache use ssl v3. El cliente http de Apache existe por separado de las bibliotecas estándar de Java SSL / TLS.

Hay otra pregunta de que no recibió respuestas: ¿Cómo deshabilitar SSLv3 en Apache HttpClient?

Este enlace parece más prometedor: https://discretemkt.wordpress.com/2014/11/16/commons-httpclient-can-disable-sslv3/

Allí, la línea clave es

Protocol.registerProtocol(scheme, customHttps);

Esa llamada aparece para permitirle omitir la fábrica ssl existente. Si ejecuta ese código primero, puede funcionar, suponiendo que las versiones del cliente http de apache son compatibles.

También tenga en cuenta que TLS 1.0 también se considera inseguro en estos días. TLS 1.2 y 1.3 y el estándar ahora.


Prueba esto:

public class ClientSSLSocketFactory { public static SSLSocketFactory getSocketFactory(Context context) { try { X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }; SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, new TrustManager[]{tm}, new SecureRandom()); SSLSocketFactory ssf = SSLCertificateSocketFactory.getDefault(10000, new SSLSessionCache(context)); return ssf; } catch (Exception ex) { Log.e("ssl", "Error during the getSocketFactory"); ex.printStackTrace(); return null; } } }

Y al crear la cola:

sRequestQueue = Volley.newRequestQueue(context, new HurlStack(null, ClientSSLSocketFactory.getSocketFactory()));

Espero eso ayude.