Android Volley的使用(三)Volley中如何使用https
来源:互联网 发布:洛阳达内大数据培训 编辑:程序博客网 时间:2024/06/04 19:56
概念
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);
- Android Volley的使用(三)Volley中如何使用https
- Android中关于Volley的使用(三)认识Volley的架构
- Android中关于Volley的使用(三)认识Volley的架构
- Android中关于Volley的使用(三)认识Volley的架构
- Android中关于Volley的使用(三)认识Volley的架构
- Android Volley框架的使用(三)
- Android Volley框架的使用(三)
- Android中关于Volley的使用(三)认识 CacheDispatcher
- Volley的使用(三)
- Volley的https的使用
- android volley(三)使用Volley加载网络图片
- Android Volley的使用
- android volley的使用
- 8.18 volley使用https
- Android Volley框架使用(三)
- Android Volley框架使用(三)
- Android中关于Volley的使用(零)Android中下载编译Volley
- Android中关于Volley的使用(零)Android中下载编译Volley
- leetcode 13. Roman to Integer
- LIst(“”) 长度为1 ?????
- Java内存相关知识整理
- 6. 用冒泡法实现对10个整数按从小到大的顺序排序输出
- 固定U盘盘符原理
- Android Volley的使用(三)Volley中如何使用https
- Pytorch学习笔记(一):pytorch的安装-Ubuntu14.04
- Sort排序====javascript函数另一种写法
- 6. 用冒泡法实现对10个整数按从小到大的顺序排序输出
- 体系架构,TCP/UDP,http
- ActiveMQ服务器之间传输对象,项目A发送对象到项目B接收发送对象《一》
- 数组总结
- 数据结构心得总结(持久更新)
- HDU 1173 采矿