Android Volley的使用(三)Volley中如何使用https
2017-06-15 20:09
183 查看
概念
https(Hyper Text TransferProtocol over Secure Socket Layer)简单讲就是在http中加入了SSL(Secure Sockets Layer,安全套接层)层的安全版本。https请求是安全的,所以请求过程中不可以被抓包。在典型的 SSL 使用场景中,会使用一个包含公钥及与其匹配的私钥的证书配置服务器。让客户端也拥有其信任的一个或多个证书集。如果请求的URL地址时发现证书不在此集合中,则不会信任服务器而请求失败。但是这样做也存在缺点。服务器在后续时间里可能存在升级更强的密钥,使用新的公钥替换证书中的公钥。这时由于客户端不能及时更新的话就会出现问题。
为弥补这些缺点,通常使用来自知名颁发者(称为证书颁发机构 (CA))发放的证书配置服务器。主机平台一般包含其信任的知名 CA 的列表。从 Android 4.2 (Jelly Bean) 开始,Android 目前包含在每个版本中更新的100 多个 CA。CA 具有一个证书和一个私钥,这点与服务器相似。为服务器发放证书时,CA 使用其私钥签署服务器证书。然后,客户端可以验证该服务器是否具有平台已知的 CA 发放的证书。详细可以参考官方说明https://developer.android.com/training/articles/security-ssl.html。
实现1
根据上面概念介绍,如果服务器是使用来自知名证书颁发机构发放的证书配置,那么在Android里会自动帮忙我们去验证该证书是否有效,我们在使用Volley请求网络时,根本就是不需要做任何事情,只需要将http URL改成https URL即可。实现2
如果服务器没有使用第三方知名证书颁发机构发放的证书配置,是通过典型使用场景,即使用一个包含公钥及与其匹配的私钥的证书配置服务器。那么也需要客户端配置与其匹配的证书。我们在《Android Volley的使用(一)基本网络请求》中介绍到可以通过代码RequestQueue requestQueue =Volley.newRequestQueue(getApplicationContext());
来创建请求队列RequestQueue对象。其实我们从源码中可以发现,newRequestQueue方法还有一个重载的版本:newRequestQueue(Context context, HttpStack stack)。那么客户端配置证书使用如下:
SSLSocketFactory sslSocketFactory =initSSLSocketFactory(); HurlStack stack = new HurlStack(null,sslSocketFactory); RequestQueue requestQueue =Volley.newRequestQueue(mContext, stack);
private final String RFC ="XXX..."; /** * 生成SSLSocketFactory * 这里的代码与之前相比,没有什么不同 * *@return */ private SSLSocketFactoryinitSSLSocketFactory() { //生成证书:Certificate CertificateFactory cf = null; SSLSocketFactory factory = null; try { cf = CertificateFactory.getInstance("X.509"); InputStream caInput = new ByteArrayInputStream(RFC.getBytes()); // 通过证书生成的RFC格式数据字符串 //InputStream caInput = new BufferedInputStream(newFileInputStream("xxx.crt")); // 证书文件 Certificate ca = null; try { ca = cf.generateCertificate(caInput); } finally { try { caInput.close(); } catch (IOException e) { e.printStackTrace(); } } //初始化公钥:keyStore String keyType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); //初始化TrustManagerFactory String algorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory managerFactory =TrustManagerFactory.getInstance(algorithm); managerFactory.init(keyStore); //初始化sslContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, managerFactory.getTrustManagers(), null); factory = sslContext.getSocketFactory(); }catch (CertificateException e) { e.printStackTrace(); }catch (NoSuchAlgorithmException e) { e.printStackTrace(); }catch (KeyStoreException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }catch (KeyManagementException e) { e.printStackTrace(); } return factory; }
实现3
这种方法属性比较极端的做法,就是跳转证书验证。其实使用https请求验证是否合法,在Volley中主要是HostnameVerifier接口中的verify方法进行验证,所以如果我们在此方法中返回true,则可以跳过证书的验证,实现如下:新建SsX509TrustManager类,并继承X509TrustManager
public class SsX509TrustManager implementsX509TrustManager { 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 { //To change body of implemented methods use File | Settings | FileTemplates. } @Override public void checkServerTrusted(java.security.cert.X509Certificate[]x509Certificates, String s) throws java.security.cert.CertificateException { //To change body of implemented methods use File | Settings | FileTemplates. } public boolean isClientTrusted(X509Certificate[] chain) { return true; } public boolean isServerTrusted(X509Certificate[] chain) { return true; } @Override public X509Certificate[] getAcceptedIssuers() { return _AcceptedIssuers; } /** * 允许所有的SSL请求,添加在new StringRequest()之前 */ 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 SsX509TrustManager()}; } 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()); } }
然后在创建请求Request对象前加上一行代码:SsX509TrustManager.allowAllSSL();即可,如:
RequestQueue requestQueue =Volley.newRequestQueue(getApplicationContext()); SsX509TrustManager.allowAllSSL(); StringRequest stringRequest = newStringRequest(Request.Method.GET, "https://kyfw.12306.cn/otn/regist/init", new Response.Listener<String>() { @Override public void onResponse(String s) { // 请求成功 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { // 请求失败 } }); requestQueue.add(stringRequest);
相关文章推荐
- 如何使用WebView访问https的url——处理SslError
- 如何通过手机客户端Android、Iphone 等访问要求使用客户端证书SSL加密的https网站
- Android Volley完全解析(二),使用Volley加载网络图片
- 如何检测当前是否正在使用HTTPS协议【发送HTTPS这个头给php-fpm】
- Android Volley完全解析(二),使用Volley加载网络图片
- 如何使用CInternetSession打开https网站
- Android Volley完全解析(二),使用Volley加载网络图片
- Android Volley完全解析(二),使用Volley加载网络图片
- Android Volley完全解析(二) , 使用Volley加载网络图片
- iOS开发工具-如何使用网络封包分析工具Charles,通过配置proxy对http、https、tcp、udp 等协议的请求响应过程交互信息进行分析、判断、解决我们移动开发中的遇到的各种实际问题。
- 如何使用WebView访问https的url——处理SslError
- 如何在Windows+VS2005使用最新静态libcurl 7.35.0获取网页数据,支持HTTPS
- Android如何使用WebView访问https的网站
- Android Volley完全解析(二),使用Volley加载网络图片
- 如何稳定地使用 Google 搜索https://encrypted.google.com/
- 如何使用php判断服务器是否是HTTPS连接
- Android Volley完全解析(二),使用Volley加载网络图片
- Android Volley完全解析(二),使用Volley加载网络图片
- Android Volley完全解析(二),使用Volley加载网络图片
- Android Volley入门到精通:使用Volley加载网络图片(示例,出错代码)