使用Android Volley发出HTTPS请求

我正在尝试使用此代码进行https请求:

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

但我得到这个错误:

com.android.volley.NoConnectionError:javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未find证书path的信任锚点。

需要注意的两点:

  1. HTTPS证书是有效的。 在浏览器中轻松打开,不会有任何警告。
  2. 上面的代码工作正常与HTTP链接。

我实际上需要知道在Android Volley框架中是否有任何开关/选项,我可以使用它来成功打开HTTPS URL?

可能这个链接将对你有所帮助: 使用Android Volley With Self-Signed SSL Certificate

大概这些代码可能对你有帮助:

1.创build一个实现X509TrustManagerHttpsTrustManager类:

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

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

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

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

 new NukeSSLCerts().nuke(); 

它会让排除信任所有的SSL证书。

我无法打开由@ Ogre_BGR提供的链接,但浏览networking时,我发现在下面的smanikandan14 Github中完成了实际的实现。 查看他的SSl 连接的解释,以更多地了解它。

到目前为止,唯一的答案是增加一个不可信的证书作为解决scheme,但是由于您的浏览器没有抱怨,通常意味着Volley找不到完成完整信任链的中间证书。

它发生在我身上的LetsEncrypt证书。 大多数浏览器已经有这样的中间证书,所以在浏览器上看起来很好,但是Volley显然缺less一些东西。

解决scheme
将中间证书添加到您的web服务器configuration。 对于Apache,你可以按照这个参考:
https://access.redhat.com/solutions/43575

对于LetsEncrypt具体是这个文件: /etc/letsencrypt/live/your.website.com/chain.pem所以除了你的CertificateFile和KeyFile你应该已经有工作,你现在有这第三行:

 SSLCertificateChainFile /etc/letsencrypt/live/your.website.com/chain.pem 

只需添加该行,重新启动apache,Volley不会再抱怨,并且不会引入任何安全漏洞!

这可能有几个原因,包括:

  • 颁发服务器证书的CA是未知的
  • 服务器证书不是由CA签名的,而是自签名的
  • 服务器configuration缺less中间CA.

来自android的官方文档

解决scheme:您可以在请求中提供证书文件