Android 排球错误:“找不到证书路径的信任锚”,仅在真实设备中,而不是模拟器中

新手上路,请多包涵

我的 Android 应用程序出现问题,在我使用 volley 进行网络请求的其中一个片段中:

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

在真实设备上出现以下错误(运行 API23):

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

在运行相同 API 版本的 AVD 中,它工作正常。我检查了其他类似的线程,但找不到答案。

谢谢你的帮助。

编辑:如果有人遇到同样的错误,请确保您的证书没有任何问题( http://developer.android.com/intl/pt-br/training/articles/security-ssl.html#CommonProblems

原文由 Sammy Patenotte 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

尝试将此功能添加到您的应用程序中:

     /**
     * 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) {
        }
    }

然后在您的应用程序 onCreate 中调用它。

更新:

此代码不相关,不应使用!它被谷歌禁止。欲了解更多信息,请看 这里

原文由 OShiffer 发布,翻译遵循 CC BY-SA 3.0 许可协议

以防万一有人仍然使用 Volley …

按照此处的说明进行操作:

https://developer.android.com/training/articles/security-ssl#java

下载证书文件 (.crt),将其放入您的资产目录(在您的 java 和 res 目录旁边),然后更改以下代码:

 InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));

使用资产中的文件:

 InputStream caInput = new BufferedInputStream(getAssets().open("load-der.crt"));

忘记后面的部分

// Tell the URLConnection to use a SocketFactory from our SSLContext

并改为添加一行:

 HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

在建立任何连接之前运行此代码。

就这样。

原文由 Ivan Ketler 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题