OkHttp Trust Certificate

In my Android application, I need to fulfill some request to my server using the OkHttp library. I have an ssl certificate, which consists of four parts:

  • AddTrustExternalCARoot.crt
  • COMODORSAAddTrustCA.crt
  • COMODORSADomainValidationSecureServerCA.crt
  • www_mydomain_com.crt

I imported all the parts in portecle 1.9, then I set my keystore password and I exported the .bks certificate.

Then I pasted this mycert.bks file into the res / raw folder of my application project. Now I am trying to connect to my server using https using this code:

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; } 

But I get an exception, this is 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) 

Where is the problem?

UPDATE: I made many attempts in this library, and I discovered this:

  • If I make a request to https: \ link.com OkHttp library will automatically trust all certificates.
  • If I want to trust only my certificate, I have to make the decision that I published above.
  • If I do not want to accept all hosts, but without using my certificate, I can use hostnameVerifier as a BNK clause.

But why did I post a question, does my solution work? Because I'm stupid, and I made a request to my vps url (vpsxxx.net/directory.php), and not to my domain (mydomain.it/directory.php).

Obviously, the SSL certificate applies to my domain, not my vps.

I hope this can be helpful to someone.

PS: Sorry for my English !: D

+4
source share
1 answer

Suppose your server application is hosted inside a server machine that has a server certificate in which "Issued to" has "localhost" , for example. Then inside the verify method you can check "localhost" .

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

You can read more at the following links:

  • HostnameVerifier

    It should be used during a handshake if the hostname of the URL does not match the name of the peer authentication node.

  • Common host name verification issues

    One of the reasons for this may be due to a server configuration error. the server is configured with a certificate that does not have an object or specify alternative name fields that correspond to the server on which you are trying to reach ...

You can then use the host name verifier in your application by calling client.setHostnameVerifier(hostnameVerifier); . Hope this helps!

P / S: another workaround is return true; inside the verify method, however, it is not recommended.

+3
source

Source: https://habr.com/ru/post/1233531/


All Articles