使用Android Volley发出HTTPS请求

Abd*_*aib 52 https android android-volley

我正在尝试使用此代码发出https请求:

RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
request = new Request<String>(Request.Method.GET,"https://devblahblahblah.com/service/etc",errListener);
Run Code Online (Sandbox Code Playgroud)

但我收到这个错误:

com.android.volley.NoConnectionError:javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚.

有两点需要注意:

  1. HTTPS证书有效.轻松打开,浏览器没有任何警告.
  2. 上面的代码适用于HTTP链接.

我实际上需要知道Android Volley框架中是否有任何交换机/选项,我将成功点击HTTPS URL?

小智 54

以下这些代码可能对您有所帮助:

1.创建一个HttpsTrustManager实现的类X509TrustManager:

public class HttpsTrustManager implements X509TrustManager {

    private static TrustManager[] trustManagers;
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};

    @Override
    public void checkClientTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    @Override
    public void checkServerTrusted(
            java.security.cert.X509Certificate[] x509Certificates, String s)
            throws java.security.cert.CertificateException {

    }

    public boolean isClientTrusted(X509Certificate[] chain) {
        return true;
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return true;
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return _AcceptedIssuers;
    }

    public static void allowAllSSL() {
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }

        });

        SSLContext context = null;
        if (trustManagers == null) {
            trustManagers = new TrustManager[]{new HttpsTrustManager()};
        }

        try {
            context = SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }

        HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }

}
Run Code Online (Sandbox Code Playgroud)

2. HttpsTrustManager.allowAllSSL()在发出https请求之前添加:

HttpsTrustManager.allowAllSSL();
String  tag_string_req = "string_req";
StringRequest strReq = new StringRequest(Request.Method.POST,
        your_https_url, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        Log.d(TAG, "response :"+response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        VolleyLog.d(TAG, "Error: " + error.getMessage());
    }
}){
    @Override
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<String, String>();
        params.put("username", "max");
        params.put("password", "123456");
        return params;
    }
};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
Run Code Online (Sandbox Code Playgroud)

  • 除了您实际上没有验证服务器证书之外,这一切都很好.除非您希望将用户暴露给各种SSL攻击,否则请务必不要在生产中部署它. (18认同)
  • 这不适合生产. (3认同)
  • 如果您使用它,您的应用将在 Google Play 中被拒绝。 (2认同)

Sam*_*Das 10

你可以添加这个类并从onCreate方法中执行它

new NukeSSLCerts().nuke();
Run Code Online (Sandbox Code Playgroud)

它将使凌空信任所有SSL证书.

  • 完美的发展 (2认同)
  • 从2017年3月1日起,Google可以阻止您的应用:https://support.google.com/faqs/answer/7188426"从2017年3月1日开始,Google Play将阻止发布使用不安全实施的任何新应用或更新HostnameVerifier.您发布的APK版本将不受影响,但除非您解决此漏洞,否则将阻止对该应用的任何更新." (2认同)