javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found java java

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found


The reason this occur is the JVM/Dalvik haven't not confidence in the CA certificates in the system or in the user certificate stores.

To fix this with Retrofit, If you are used okhttp, with another client it's very similar.
You've to do:

A). Create a cert store contain public Key of CA. To do this you need to launch next script for *nix. You need openssl install in your machine, and download from https://www.bouncycastle.org/ the jar bcprov-jdk16-1.46.jar. Download this version not other, the version 1.5x is not compatible with android 4.0.4.

#!/bin/bashif [ -z $1 ]; then  echo "Usage: cert2Android<CA cert PEM file>"  exit 1fiCACERT=$1BCJAR=bcprov-jdk16-1.46.jarTRUSTSTORE=mytruststore.bksALIAS=`openssl x509 -inform PEM -subject_hash -noout -in $CACERT`if [ -f $TRUSTSTORE ]; then    rm $TRUSTSTORE || exit 1fiecho "Adding certificate to $TRUSTSTORE..."keytool -import -v -trustcacerts -alias $ALIAS \      -file $CACERT \      -keystore $TRUSTSTORE -storetype BKS \      -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \      -providerpath $BCJAR \      -storepass secretecho "" echo "Added '$CACERT' with alias '$ALIAS' to $TRUSTSTORE..."

B). Copy the file truststore mytruststore.bks in res/raw of your projecttruststore location

C). Setting SSLContext of the connection:

.............okHttpClient = new OkHttpClient();try {    KeyStore ksTrust = KeyStore.getInstance("BKS");    InputStream instream = context.getResources().openRawResource(R.raw.mytruststore);    ksTrust.load(instream, "secret".toCharArray());    // TrustManager decides which certificate authorities to use.    TrustManagerFactory tmf = TrustManagerFactory        .getInstance(TrustManagerFactory.getDefaultAlgorithm());    tmf.init(ksTrust);    SSLContext sslContext = SSLContext.getInstance("TLS");    sslContext.init(null, tmf.getTrustManagers(), null);    okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());} catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) {    e.printStackTrace();}.................


This can happen for several reasons, including:

  1. The CA that issued the server certificate was unknown
  2. The server certificate wasn't signed by a CA, but was self signed
  3. The server configuration is missing an intermediate CA

please check out this link for solution: https://developer.android.com/training/articles/security-ssl.html#CommonProblems


Fix for Android N & above:I had similar issue and mange to solve it by following steps described in https://developer.android.com/training/articles/security-config

But the config changes, without any complicated code logic, would only work on Android version 24 & above.

Fix for all version, including version < N:So for android lower then N (version 24) the solution is to via code changes as mentioned above. If you are using OkHttp, then follow the customTrust:https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java