Search code examples
androidandroid-volley

Android volley error: "Trust anchor for certification path not found", only in real device, not emulator


I'm having a problem in my Android app, in one of my fragments I use volley to do a network request:

JsonObjectRequest request = new JsonObjectRequest(
            Request.Method.POST,
            CustomNetworkManager.getInstance(this.getActivity().getApplicationContext()).getRequestUrl(url),
            requestData,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    // process response
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("FeedFragment", "Volley error: " + error.toString());
                }
            });

On a real device I get the following error (running API23):

D/FeedFragment: Volley error: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

In an AVD running the same API version it is working fine. I checked other similar threads but couldn't find an answer.

Thanks for your help.

edit: If anyone faces the same error, make sure you don't have any problems with your certificates (http://developer.android.com/intl/pt-br/training/articles/security-ssl.html#CommonProblems)


Solution

  • try to add this function to your Application:

        /**
         * Enables https connections
         */
        @SuppressLint("TrulyRandom")
        public static void handleSSLHandshake() {
            try {
                TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
    
                    @Override
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
    
                    @Override
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }};
    
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String arg0, SSLSession arg1) {
                        return true;
                    }
                });
            } catch (Exception ignored) {
            }
        }
    

    and then call it in your Application onCreate.

    UPDATE:

    This code is not relevant and shouldn't be used! it is forbidden by Google. for more information look here.