OkHttp trust certificate


diegocom

In my Android app, I need to perform some requests to the server using OkHttp library. I have an ssl certificate with four parts:

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

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

Then, inserted mycert.bks into the res/raw folder of my app project. Now I try to connect to the server via https using the following 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 the 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 tried a lot with the library and found this:

  • If I make a request to https:\link.com, the OkHttp library automatically trusts all certificates.
  • If I just want to trust my certificate, I have to do the solution posted above.
  • If I don't want to accept all hosts, but don't use my certificate, I can use the hostnameVerifier suggested by BNK.

But why is my problem solvable? Because I was stupid, I made a request to my vps url (vpsxxx.net/directory.php) instead of my domain (mydomain.it/directory.php).

Apparently the SSL certificate is for my domain but not my vps.

I hope this is useful to someone.

PS: sorry for my english! :D

bank

Let's assume your server's application is hosted inside the server with a server certificate "Issued to", "localhost"eg. Then verifyyou can verify in the inner method "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 information at the following links:

  1. hostname validator

    If the URL's hostname does not match the peer's identifying hostname, it is used during the handshake.

  2. Frequently Asked Questions about Hostname Verification

    One reason this happens is due to server misconfiguration. The server configured certificate does not have a subject or subject alternative name field that matches the server you are trying to connect to...

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

P/S: There is another temporary workaround return true;inside the verifymethod, but it is not recommended.

Related


OkHttp trust certificate

diegocom In my Android app, I need to perform some requests to the server using OkHttp library. I have an ssl certificate with four parts: AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSADomainValidationSecureServerCA.crt www_mydomain_com.crt I hav

OkHttp trust certificate

diegocom In my Android app, I need to perform some requests to the server using OkHttp library. I have an ssl certificate with four parts: AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSADomainValidationSecureServerCA.crt www_mydomain_com.crt I hav

OkHttp trust certificate

diegocom In my Android app, I need to perform some requests to the server using OkHttp library. I have an ssl certificate with four parts: AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSADomainValidationSecureServerCA.crt www_mydomain_com.crt I hav

Trust all certificates with okHttp

seato: seato: For testing, I'm trying to add a socket factory to my okHttp client that trusts everything when setting up the proxy. This has been done many times, but my implementation of the trusted socket factory seems to be missing something: class TrustEve

Trust all certificates with okHttp

seato: seato: For testing, I'm trying to add a socket factory to my okHttp client that trusts everything when setting up the proxy. This has been done many times, but my implementation of the trusted socket factory seems to be missing something: class TrustEve

Trust all certificates with okHttp

seato: seato: For testing, I'm trying to add a socket factory to my okHttp client that trusts everything when setting up the proxy. This has been done many times, but my implementation of the trusted socket factory seems to be missing something: class TrustEve

lftp trust server certificate

MayeulC When connecting to the server using lftp, I get the following problem: Certificate verification: Not trusted: no issuer was found (AA:AA:AA:[...]:AA:AA) This at least indicates that the certificate verification failed. I want to whitelist that certifi

Programmatically trust Hoverfly Java certificate

Amr Lotfy: Using Hoverfly-java to mock a web service in a unit test, and using HttpClient as the web client, found that the Hoverfly proxy settings are propagated correctly using Hoverfly, useSystemProperties()but I still get the TLS error: Unknown certificate

Force HttpClient to trust a single certificate

Andre Sneder Kirk Can you force HttpClient to trust only a single certificate? I know you can do: WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClien

Force HttpClient to trust a single certificate

Andre Sneder Kirk Can you force HttpClient to trust only a single certificate? I know you can do: WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClien

Does Android trust the StartSSL certificate?

marc_aragones I am developing an android application and I want to encrypt the data sent to the server. I've seen a lot of people saying that the best practice is to use SSL, and I found that StartSSL is free. my question is: Will Android trust my StartSSL cer

Programmatically trust Hoverfly Java certificate

Amr Lotfy: Using Hoverfly-java to mock a web service in a unit test, and using HttpClient as the web client, found that the Hoverfly proxy settings are propagated correctly using Hoverfly, useSystemProperties()but I still get the TLS error: Unknown certificate

Programmatically trust Hoverfly Java certificate

Amr Lotfy: Using Hoverfly-java to mock a web service in a unit test, and using HttpClient as the web client, found that the Hoverfly proxy settings are propagated correctly using Hoverfly, useSystemProperties()but I still get the TLS error: Unknown certificate

Programmatically trust Hoverfly Java certificate

Amr Lotfy: Using Hoverfly-java to mock a web service in a unit test, and using HttpClient as the web client, found that the Hoverfly proxy settings are propagated correctly using Hoverfly, useSystemProperties()but I still get the TLS error: Unknown certificate

android doesn't trust certificate

Yar I run openssl s_client -connect mywishboard.com:443 | openssl x509 -noout -subject -issuerand get the following information about the certificate (set by the client developer) depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN =

android doesn't trust certificate

Yar I run openssl s_client -connect mywishboard.com:443 | openssl x509 -noout -subject -issuerand get the following information about the certificate (set by the client developer) depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN =

How to trust a certificate authority in Java?

and My application connects to an SSL web service, which uses a certificate to verify its identity. Recently this certificate has been changed and part of my application is failing because it is not signed by a trusted authority. The service recommends that to

Force HttpClient to trust a single certificate

André Snede Kock Can you force HttpClient to trust only a single certificate? I know you can do: WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClient

Does Android trust the StartSSL certificate?

marc_aragones I am developing an android application and I want to encrypt the data sent to the server. I've seen a lot of people saying that the best practice is to use SSL, and I found that StartSSL is free. my question is: Will Android trust my StartSSL cer

Programmatically trust Hoverfly Java certificate

Amr Lotfy: Using Hoverfly-java to mock a web service in a unit test, and using HttpClient as the web client, found that the Hoverfly proxy settings are propagated correctly using Hoverfly, useSystemProperties()but I still get the TLS error: Unknown certificate

Force HttpClient to trust a single certificate

André Snede Kock Can you force HttpClient to trust only a single certificate? I know you can do: WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClient

OkHttp with certificate pinning

Bank My Android project (OkHttp 3.3.1) currently works with my HTTPS web service (my PC, IIS web server, Asp.Net Web API, self signed certificate) Helper method: private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreExcept

OkHttp certificate chain validation

Chandan I am using an Okhttp client to call another REST service. Does OkHttp validate the entire certificate chain up to the root certificate when making an https call? Jesse Wilson OkHttp relies on the platform's SSLSocket to do that in the handshake. The ce

OkHttp certificate chain verification

Changdan We are using Okhttp client to call other REST services. When making https calls, does OkHttp validate the entire certificate chain until the root certificate is obtained? Jesse Wilson OkHttp relies on the platform's SSLSocket to do this in the handsha

OkHttp with certificate pinning

Bank My Android project (OkHttp 3.3.1) currently works with my HTTPS web service (my PC, IIS web server, Asp.Net Web API, self signed certificate) Helper method: private SSLSocketFactory getSSLSocketFactory() throws CertificateException, KeyStoreExcept

OkHttp certificate chain validation

Chandan I am using an Okhttp client to call another REST service. Does OkHttp validate the entire certificate chain up to the root certificate when making an https call? Jesse Wilson OkHttp relies on the platform's SSLSocket to do that in the handshake. The ce

OkHttp certificate chain verification

Changdan We are using Okhttp client to call other REST services. When making https calls, does OkHttp validate the entire certificate chain until the root certificate is obtained? Jesse Wilson OkHttp relies on the platform's SSLSocket to do this in the handsha

OkHttp certificate chain verification

Changdan We are using Okhttp client to call other REST services. When making https calls, does OkHttp validate the entire certificate chain until the root certificate is obtained? Jesse Wilson OkHttp relies on the platform's SSLSocket to do this in the handsha

OkHttp certificate chain validation

Chandan I am using an Okhttp client to call another REST service. Does OkHttp validate the entire certificate chain up to the root certificate when making an https call? Jesse Wilson OkHttp relies on the platform's SSLSocket to do that in the handshake. The ce