https协议就是http+ssl协议,以下图所示为其链接过程:
1.https请求
客户端向服务端发送https请求;
2.生成公钥和私钥
服务端收到请求以后,生成公钥和私钥。公钥至关因而锁,私钥至关因而钥匙,只有私钥才可以打开公钥锁住的内容;
3.返回公钥
服务端将公钥(证书)返回给客户端,公钥里面包含有不少信息,好比证书的颁发机构、过时时间等等;
4.客户端验证公钥
客户端收到公钥以后,首先会验证其是否有效,如颁发机构或者过时时间等,若是发现有问题就会抛出异常,提示证书存在问题。若是没有问题,那么就生成一个随机值,做为客户端的密钥,而后用服务端的公钥加密;
5.发送客户端密钥
客户端用服务端的公钥加密密钥,而后发送给服务端。
6.服务端收取密钥,对称加密内容
服务端收到通过加密的密钥,而后用私钥将其解密,获得客户端的密钥,而后服务端把要传输的内容和客户端的密钥进行对称加密,这样除非知道密钥,不然没法知道传输的内容。
7.加密传输
服务端将通过加密的内容传输给客户端。
8.获取加密内容,解密
客户端获取加密内容后,用以前生成的密钥对其进行解密,获取到内容。web
https也不是绝对安全的,以下图所示为中间人劫持攻击,中间人能够获取到客户端与服务器之间全部的通讯内容。
中间人截取客户端发送给服务器的请求,而后假装成客户端与服务器进行通讯;将服务器返回给客户端的内容发送给客户端,假装成服务器与客户端进行通讯。
经过这样的手段,即可以获取客户端和服务器之间通讯的全部内容。
使用中间人攻击手段,必需要让客户端信任中间人的证书,若是客户端不信任,则这种攻击手段也没法发挥做用。安全
2、中间人攻击的预防服务器
形成中间人劫持的缘由是 没有对服务端证书及域名作校验或者校验不完整,为了方便,直接采用开源框架默认的校验方式进行https请求网络
如volleyapp
OKhttp3.0框架
预防方法:优化
预防方式有两种ui
1 、针对安全性要求比较高的 app,可采起客户端预埋证书的方式锁死证书,只有当客户端证书和服务端的证书彻底一致的状况下才容许通讯,如一些银行类的app,但这种方式面临一个问题,证书过时的问题,因证书有必定的有效期,当预埋证书过时了,只有经过强制更新或者要求用户下载证书来解决。加密
以volley为例:校验的实现方式以下spa
经过预埋证书建立 SSLSocketFactory;
private static SSLSocketFactory buildSSLSocketFactory(Context context, int certRawResId) { KeyStore keyStore = null; try { keyStore = buildKeyStore(context, certRawResId); } catch (KeyStoreException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = null; try { tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("TLS"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } try { sslContext.init(null, tmf.getTrustManagers(), null); } catch (KeyManagementException e) { e.printStackTrace(); } return sslContext.getSocketFactory();
生成 通过ssl校验及 域名校验的connection
2 针对安全性要求通常的app,可采用经过校验域名,证书有效性、证书关键信息及证书链的方式
以volley为例,重写HTTPSTrustManager 中的checkServerTrusted 方法,同时开启域名强校验
三 Webview的HTTPS安全
目前不少应用都用webview加载H5页面,若是服务端采用的是可信CA颁发的证书,在 webView.setWebViewClient(webviewClient) 时重载 WebViewClient的onReceivedSslError() ,若是出现证书错误,直接调用handler.proceed()会忽略错误继续加载证书有问题的页面,若是调用handler.cancel()能够终止加载证书有问题的页面,证书出现问题了,能够提示用户风险,让用户选择加载与否,若是是须要安全级别比较高,能够直接终止页面加载,提示用户网络环境有风险:
不建议直接用handler.proceed()。若是webview加载https须要强校验服务端证书,能够在 onPageStarted() 中用 HttpsURLConnection 强校验证书的方式来校验服务端证书,若是校验不经过中止加载网页。固然这样会拖慢网页的加载速度,须要进一步优化,具体优化的办法不在本次讨论范围,这里也不详细讲解了。