抓包
一 在应用层抓包(http/https)
抓http
客户端与服务器之间为明文通信。 请随意抓包
抓https
客户端与服务器之间为加密通信。 那这加密通信的原理是什么?
先解释几个名词:
什么是加密
通过编程,用一段俗称密码的东西,通过某种算法跑一下,对要加密的明文内容进行重新编码,是它变成不可读的乱码。那么你想看懂这段加密过的乱码,就需要经过解密,解密需要知道算法和密码。
加密算法都是基于数学原理,算法一般都是公开的,大家都知道有哪些算法,实现的方法。
对称加密,传统的加密算法,就是加密和解密用的都是一个密码,这很好理解。像电视剧里的谍报战,我预先知道了你的算法,特工只要找到敌方的密码本,就能解密了。 那有没有可能加密和解密分别用不同的密码?别说还真有!
非对称加密(描述不准,知道个意思就行了)
基于大素数的因质分解原理,能找到这样的一个数,它能分解成两个数的乘积,但你如果只知道两个数中的一个,是无法推算出另一个数的。同理,如果你随机生成两个很长的字符串,能用来合成出一个唯一的字符串,这个运算费点时间,但很容易完成。 这就是RSA算法。通过算法可以随机生成这样的两个字符串,称为一对公钥和私钥,知道算法,并且拥有其中任意的一把钥匙,你能解开用另一把钥匙加密过的密文。 但你几乎不可能通过手头的这把钥匙逆推出另一把钥匙,这保证了钥匙的安全。 为了能快速加解密,一般公钥比较短,私钥比较长。 私钥不传播不公开,所以称为私钥, 公钥公开发布出去。
哈希(hash),哈希函数,一种散列值算法,而所谓散列值,就是指对一段文本进行哈希运算,能计算出一个值,这个值很简短,而且对这段文本来说是唯一的,一旦输入的文本有丝毫改变,计算出散列值就将不同。根据这个特点,散列值可以形象的被称为这段文本的指纹,用来识别文本有没有被篡改。
CA证书
非对称加密看起来很美好, 我要和某人进行加密通信,只要相互交换各自的公钥给对方,通信时,我用对方的公钥加密信息发给对方,对方用自己的私钥解密读取信息,对方用我的公钥加密信息回复给我,我用自己的私钥解密读取信息,而这个过程完全可以由软件自动完成,用户可以无感知。完美!但是等等,这里面有个问题,一开始:我们是如何互换公钥的? 你私下(线下)交换没问题。但现在网络时代,一切暴露在线上的数据都不安全,你如何确定对方发给你的公约就是对方的,而不是被一个第三者夹在你们中间,劫持了你们的通信后,把他自己的公钥发给了你们双方?你们将毫无所知,你们的通信对他透明,这个后果很可怕不是么。
公钥的分发实际上并没有什么较好的办法。 所以就有了现在的CA机构,一种大家公认的证书颁发机构。
什么是CA?先不急,我们再来看一个概念:证书
证书又是什么? 知道身份证吧?一种用来证明你是你的东西,我们拿二代身份证举例,它有这样的特点:身份证表面既用明文写清楚了你的身份信息,谁都可以阅读。内部又有加密芯片用于机器解读验证信息是否一直,防止篡改。
证书就是数字世界的身份证。
在数字世界里,证书实际上就是一段文本,里面同样有你的基本信息如名称,电子邮件,核心内容是你的公钥信息。但如果仅仅只有这些的话,还不能被称为证书,因为这些明文信息能被随意篡改。怎么才能防止篡改?对了,加密。但你也不能直接把整个正文都给加密了。这样谁能看到内容呢?所以,作为证书,它同样有这样的要求:1.文本信息是明文的,谁都能看到。2.对这段明文信息的特征做加密,需要时可以被验证是否篡改。
证书区别于普通文本的地方是:证书的正文信息后面,附加了一段CA机构的签名信息(密文)。
这个签名又是什么鬼,用笔签吗?其实是这样的:
- 1.先对证书的正文信息进行hash运算,得到其指纹。
- 2.CA用自己的私钥对指纹信息进行加密,加密后的密文随附在正文后面,这就叫签名
包含签名的这段文本,现在可以被称为证书了,无论谁拿到,都可以阅读其正文,但如果你一旦篡改了正文,那么正文的指纹就改变了,与签名中被加密保存的原始正文的指纹肯定不一样!
哈希(hash),哈希函数,一种散列值算法,而所谓散列值,就是指对一段文本进行哈希运算,能计算出一个值,这个值很简短,而且对这段文本来说是唯一的,一旦输入的文本有丝毫改变,计算出散列值就将不同。根据这个特点,散列值可以形象的被称为这段文本的指纹,用来识别文本有没有被篡改。
我们各自都拥有了证书以后,现在我要和某人进行加通信的过程变成这样:1第一步还是互换公钥,更确切的说是互换(包含公钥信息的)证书,拿到对方的证书后,我们先对证书的正文部分进行hash计算出它的指纹,与从证书签名中保存的指纹进行对比,如果一致,说明证书是未被篡改过的,那么我就可以信任这个证书中的公钥。2,第二步接下来我们就可以愉快的使用对方的公钥发送加密信息,进行通信了。
不过这里面还是有个疑问:我是怎么去解密这个证书里面的签名,获得里面的指纹呢? 它被CA的私钥加密了,我需要CA的公钥来解密呀。
那怎么获得CA的公钥?别慌,你电脑的操作系统或者浏览器里面已经预装了所有CA机构的证书。因为CA机构与系统厂商和浏览器厂商合作了,这些预装都在线下完成,确保安全。
CA的证书里自然有它的明文公钥信息了,而且既然是证书格式,肯定签名过了,还是自己给自己签的。你能用这个公钥去解密签名,验证指纹信息。 像这种自己给自己签发的证书,叫做自签证书,就是自己发证书证明我是我!当然只有CA才有资格这样做啦。
好了,现在CA机构成立 ,所有有分发公钥需求的人都可以去申请自己的证书了。所以市面上几乎所有的证书都是源自CA的签发,CA的证书因此被称为根证书。
CA下面还有二级或多级级代理机构,颁发的证书就称为二级或三级证书之类的。
好了,让我来总结一下:
证书的真伪验证是一个链条式的逐级验证的过程,这被称为信任链:
- CA用私钥自签生成根证书(内含CA公钥),预装到你的操作系统或浏览器,
- CA用私钥给二级机构签发二级证书(内含二级机构公钥),或许也已经出现在你的系统中,你能用根证书验证它
- 二级机构给各企业或网站或用户签发证书(内含用户公钥),用户使用证书来安全的分发公钥
- 最终用户获取到某个证书后,可以通过预装在自己系统中的上级证书,来验证该证书是否有效
放张图:

绕了个大弯,终于可以回来了
让我们回到https通信原理上来,我们知道用https://www.baidu.com方式浏览网页的话,当你按下回车时,浏览器首先要做的就是从对方的服务器上下载该网站的证书,并验证证书有效后,才会开始建立https连接。
那么又有个疑问来了? 刚才说加密通信的时候不是说好了互换公钥的吗? 好像服务器并没有向我要证书呢?还能不能愉快的玩耍了?
别慌,事实上,作为一个网站,服务于万千用户,它根本不care是谁在浏览它。care的是我们用户,怕访问了假网站,所以我们要验证网站,网站不需要验证我们(事实上也要的,当它要向你收钱的时候,嘿嘿~~)
所以https通信的证书是单向传递,不是互换。
实际上,基于性能的考量,https也并没有直接使用非对称加密来加密整个通信过程,而是只使用了非对称加密的方式来交换一个密码,再用这个密码完成后续的对称加密通信,过程如下:
- 客户端向服务器请求时,服务器先返回包含其公钥的证书。
- 客户端验证服务器证书的合法性后,生成一个随机数通过该公钥加密发给服务器,服务器通过自己的私钥解密得到这个随机数,完成密码交换。
- 后续客户端与服务器通过交换的随机数对数据进行对称加解密。
再继续回到抓包的主题上,抓https关键就是获得这个密码,方法就是在需要抓包的目标上先安装抓包软件的证书,把这个抓包软件自我签发的证书设置为信任或放到根证书区域完全信任。接着,在目标上配置代理,把它所有的流量导向抓包软件,抓包软件截获目标发往服务器的通讯请求后,就能伪装成服务器(**怎么伪装?你现在不是想请求服务器的证书吗?我马上给你伪造一张发给你,因为你之前配置并信任了我的根证书,所以我现在伪造的证书被你验证通过,让你以为就是真正的服务器给你的)和目标通信(密码自然就获取到了),同时也伪装成目标与真正的服务器通信。
抓微信小程序
在Android7.0及以上的系统中,每个应用可以定义自己的可信CA集。则默认情况下,应用只会信任系统预装的CA证书,而不会信任用户安装的CA证书。
而抓包的过程,无论是fiddler还是Charles,想抓https,都必须使手机安装对应工具生成的证书,这正属于用户安装的证书,将被视为不安全的证书。
so:
- 安卓系统 7.0 以下版本,不管微信任意版本,都会信任系统提供的证书 (随便抓)
- 安卓系统 7.0 以上版本,微信 7.0 * 以下版本,微信会信任系统提供的证书 (随便抓)
- 安卓系统 7.0 以上版本,微信 7.0 以上版本,微信只信任它自己配置的证书列表 (这就有点难办了)
那么对于现在最新的小程序来说,最关键的就是解决证书的信任问题
给几个解决方案参考:
- root系统,把证书放到系统证书里。但现在8.0以上android已经不能root了
- 不能root的系统,不使用真机,咱使用模拟器可以吧,开启root,安装XPosed框架,加载JustTrustMe模块绕过证书验证
- 使用VirtualXposed,同上,只不过这个框架不需要root
- 微信版本回退到老版本,但小程序的接口能力依赖微信版本,老版本会有兼容问题
- 用苹果手机。 不同安卓系统,苹果信任证书比较方便
二 传输层抓包
前面讲的抓包,都是在应用层混的, 我们来看以下网络的四层模型。


浙公网安备 33010602011771号