OkHttp certificado de confianza

En mi aplicación android necesito ejecutar alguna solicitud a mi servidor con la biblioteca OkHttp. Tengo un certificado del ssl que consiste en cuatro porciones:

  • AddTrustExternalCARoot.crt
  • COMODORSAAddTrustCA.crt
  • COMODORESADomainValidationSecureServerCA.crt
  • Www_mydomain_com.crt

He importado todas las partes en el portecle 1.9, después fijé mi contraseña del keystore y he exportado el CERT de .bks.

Entonces he insertado mycert.bks en la carpeta res / raw de mi proyecto de aplicación. Ahora estoy intentando conectarme a mi servidor por https con este código:

OkHttpClient client = new OkHttpClient(); try{ client.setSslSocketFactory(getPinnedCertSslSocketFactory(context)); RequestBody formBody = new FormEncodingBuilder() .add("params", "xxx") .build(); Request request = new Request.Builder() .url("https:\\mydomain.com") .post(formBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); return response.body().string();; } catch (Exception e) { e.printStackTrace(); } return null; } private SSLSocketFactory getPinnedCertSslSocketFactory(Context context) { try { KeyStore trusted = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(R.raw.mycert); trusted.load(in, "mypass".toCharArray()); SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trusted); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); return sslContext.getSocketFactory(); } catch (Exception e) { Log.e("MyApp", e.getMessage(), e); } return null; } 

Pero obtengo una excepción, este es el logcat:

 10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: javax.net.ssl.SSLPeerUnverifiedException: Hostname myserver.net not verified: 10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: certificate: sha1/"mysha1string" 10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: DN: CN=www.aaa.it,OU=PositiveSSL,OU=Domain Control Validated 10-11 18:22:51.930 13604-5341/com.aaa.android.client W/System.err: subjectAltNames: [www.aaa.it, aaa.it] 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectTls(Connection.java:244) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectSocket(Connection.java:199) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connect(Connection.java:172) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:367) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:328) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:245) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.getResponse(Call.java:267) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.squareup.okhttp.Call.execute(Call.java:79) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:294) 10-11 18:22:51.940 13604-5341/com.aaa.android.client W/System.err: at com.aaa.android.client.Login$BackgroundTask.doInBackground(Login.java:277) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 10-11 18:22:51.950 13604-5341/com.aaa.android.client W/System.err: at java.lang.Thread.run(Thread.java:818) 

¿Dónde está el problema?

ACTUALIZACIÓN: He hecho muchos intentos en esta biblioteca y descubrí esto:

  • Si hago una solicitud a la biblioteca https: \ link.com OkHttp confía automáticamente en todo el certificado.
  • Si quiero confiar sólo en mi certificado, tengo que hacer la solución que he publicado anteriormente.
  • Si no quiero aceptar todo el host, pero sin usar mi certificado puedo usar hostnameVerifier como sugerir BNK.

¿Pero por qué publiqué la pregunta si mi solución funciona? Porque soy estúpido y hice la solicitud a mi url de vps (vpsxxx.net/directory.php) y no a mi dominio (mydomain.it/directory.php).

Obviamente el certificado SSL se aplica a mi dominio y no a mis vps.

Espero que esto pueda ser útil para alguien.

PS: Lo siento por mi Inglés! :RE

Supongamos que su aplicación de servidor se aloja dentro de una máquina servidor que tiene un certificado de servidor en el que "Issued to" es "localhost" , por ejemplo. Entonces, dentro del método de verify se puede verificar "localhost" .

 HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier(); return hv.verify("localhost", session); } }; 

Puede leer más en los siguientes enlaces:

  1. HostnameVerifier

    Se debe utilizar durante un apretón de manos si el nombre de host de la URL no coincide con el nombre de host de identificación de los pares.

  2. Problemas comunes con la verificación de nombre de host

    Una razón por la que esto puede suceder se debe a un error de configuración del servidor. El servidor está configurado con un certificado que no tiene un tema o sujetar campos de nombres alternativos que coincidan con el servidor al que está intentando llegar …

A continuación, puede utilizar el verificador de nombre de host en su aplicación, llamando a client.setHostnameVerifier(hostnameVerifier); . ¡Espero que esto ayude!

P / S: otra solución temporal es return true; Dentro de verify método, sin embargo, no es recomendable.

  • Error de libcurl CURLE_SSL_CACERT_BADFILE en android
  • Administrador de descargas de Android no descargar archivos desde https
  • Cómo llamar al servicio web https en Android
  • Autenticación de cliente SSL en Android 4.x
  • SSLSocketFactory establecimiento de tiempo de espera y propiedades de socket
  • Linphone Android: Error de apretón de manos de TLS con certificado autofirmado
  • Android envía la solicitud de correos https al servidor sin métodos desaconsejados
  • no se puede conectar al servidor utilizando BKS keystore
  • Keystore SHA1 diferente de cert.rsa SHA1 de APK
  • Ignorar el certificado SSL Comprobar en Android React Native
  • NogotoFail Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.