之前对这块研究了很多,在“疯狂的程序员”群里也有好几个成员提出如何防止wifi劫持的问题,所以特地写一篇文章来阐述,文章包含原理与相应的Android代码,IOS代码类似,不做展示。
先来描述一下chaless抓包的原理,http不用考虑了,一抓一个准,我们要看的是相对安全的https,有些人要问,https不是已经是安全的访问了吗?为什么还能被抓包被劫持呢?要了解这个首先得先了解https的工作原理,我这边做一个简单描述。
https工作原理:首先,https是在http的基础上新增了一种加密方式,然后https也分两种运行模式,一种是单向加密一种是双向加密,我们看到的网页https都是单向加密,双向加密出现于银行的系统,例如使用USB盾的场景。先来了解一下单向加密,单向加密要求服务端需要持有一个证书公私钥,客户端执行请求时服务端会把公钥下发给客户端,然后客户端选择一个服务端与客户端同时支持的加密算法生成一组秘钥(基本都是对称加密的秘钥),接着客户端使用公钥对要请求的数据与生成的秘钥进行加密(公钥加密,只有私钥能解密),最后把数据发送给服务端,服务端持有私钥,所以能解密出请求的数据,然后按照客户端选择的加密算法用秘钥对返回数据进行加密,再之后直接传输给客户端,客户端使用秘钥进行解密拿到所需的请求数据。
以上就是https的单向加密的流程,送流程中应该能看出可能出现问题的点在哪里。对,就在客户端获取服务端公钥那一步,如果这一步被人拦截,返回了一个第三方的公钥,那么整个通信过程都会暴露在第三方的眼皮底下,而这,就是charless抓https包的关键(当然charless需要用户手机信任他的证书,因为他的证书是免费的)。
那么,问题来了,如何防止这类拦截呢?,其实解决问题的方案很简单,本地持有真的服务端证书公钥就可以了,然后请求时做一下公钥检测,如果发现公钥非我们服务端的公钥,那么直接拒绝即可。
不过由此会引发一下后遗症,那就是证书过期且不可续,如果发生这种问题那就很麻烦,用户必须卡准某个点进行强更,这个肯定是不现实的,解决方案也很简单,提现一个月生成新的证书,然后通过接口把证书下发给客户端,客户端的证书白名单可以同时支持新老证书,那么就能无缝切换了,如果遇到一个月未登陆的用户,那么就请他去官网下载更新覆盖安装吧。
(代码下次再贴,要睡觉了)
Comments
comments powered by zero