普通HTTP请求存在的问题
HTTP 本身是明文传输的,没有经过任何安全处理。例如用户在百度搜索了一个关键字,比如“苹果手机”,中间者完全能够查看到这个信息,并且有可能打电话过来骚扰用户。也有一些用户投诉使用百度时(官网:www.fhadmin.org),发现首页或者结果页面浮了一个很长很大的广告,这也肯定是中间者往页面插的广告内容。如果劫持技术比较低劣的话,用户甚至无法访问百度。
这里提到的中间者主要指一些网络节点,是用户数据在浏览器和百度服务器中间传输必须要经过的节点。比如 WIFI 热点,路由器,防火墙,反向代理,缓存服务器等。
在 HTTP 协议下,中间者可以随意嗅探用户搜索内容,窃取隐私甚至篡改网页。不过 HTTPS 是这些劫持行为的克星,能够完全有效地防御。
所以,就有了HTTPS,使用 HTTPS 协议主要是为了保护用户隐私,防止流量劫持。
解决方法
- 使用HTTPS(方便,不过要申请证书)
- 自己对数据进行加密,讲明文传输改为密文传输((官网:www.fhadmin.org)麻烦,因为要自行进行加密解密,步骤多,容易错)
- HTTPS + 自己对数据加密(这是最麻烦,但是比较安全)
HTTPS的特点
- 内容加密。浏览器到百度服务器的内容都是以加密形式传输,中间者无法直接查看原始内容。
- 身份认证。保证用户访问的是百度服务,即使被 DNS 劫持到了第三方站点,也会提醒用户没有访问百度服务,有可能被劫持
- 数据完整性。防止内容被第三方冒充或者篡改。
HTTPS原理
流程如下:
1. 客户端发起一个https的请求,把自身支持的一系列Cipher Suite(密钥算法套件,简称Cipher)发送给服务端。
2. 服务端存在一个公匙和私匙。
3. 服务端,接收到客户端所有的Cipher后与自身支持的对比,如果不支持则连接断开,反之则会从中选出一种加密算法和HASH算法以证书的形式返回给客户端 证书中还包含了 公钥 颁证机构 网址 失效日期等等。
4. 客户端收到服务端响应后会做以下几件事
(1)验证证书的合法性
颁发证书的机构是否合法与是否过期,证书中包含的网站地址是否与正在访问的地址一致等,证书验证通过后,在浏览器的地址栏会加上一把小锁(每家浏览器验证通过后的提示不一样 不做讨论(官网:www.fhadmin.org))。
(2)生成随机密码
如果证书验证通过,或者用户接受了不授信的证书,此时浏览器会生成一串随机数,然后用证书中的公钥加密。
(3)HASH握手信息
用最开始约定好的HASH方式,把握手消息取HASH值, 然后用 随机数加密 “握手消息+握手消息HASH值(签名)” 并一起发送给服务端。
在这里之所以要取握手消息的HASH值,主要是把握手消息做一个签名,用于验证握手消息在传输过程中没有被篡改过。
5. 客户端将加密后的内容传给服务端
6. 服务端拿到客户端传来的密文,用自己的私钥来解密握手消息取出随机数密码,再用随机数密码 解密 握手消息与HASH值,并与传过来的HASH值做对比确认是否一致。
7. 然后用随机密码加密一段握手消息(握手消息+握手消息的HASH值 )给客户端。
8. 客户端用随机数解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
因为这串密钥只有客户端和服务端知道,所以即使中间请求被拦截也是没法解密数据的,以此保证了通信的安全
常用加密解密算法
- 非对称加密算法:RSA,DSA/DSS 在客户端与服务端相互验证的过程中用的是对称加密
- 对称加密算法:AES,RC4,3DES 客户端与服务端相互验证通过后,以随机数作为密钥时,就是对称加密
- HASH算法:MD5,SHA1,SHA256 在确认握手消息没有被篡改时
如何抓取HTTPS的请求数据
当站点由HTTP转成HTTPS后是更安全了,但是有时候要看线上的请求数据解决问题时却麻烦了,因为是HTTPS的请求,你就算拦截到了那也是加密的数据,没有任何意义。
HTTPS是否真的足够安全
HTTPS是安全的,因为有证书和加密机制做保障!
(官网:www.fhadmin.org)
但是,有个可怕的方法叫“ DNS劫持 ”,简单的说黑客为了绕过HTTPS,采用了SSL层剥离的技术,黑客阻止用户和使用HTTPS请求的网站之间建立SSL连接,使用户和代理服务器(攻击者所控制的服务器)之间使用了未加密的HTTP通信。
工作流程如下图:
工作原理
1. 客户端发送域名请求给 dns
2. dns通过遍历查询dns数据库,来解析此域名对应的ip,然后反馈至浏览器客户端
3. 客户端通过ip与对方建立数据连接
4. 问题就出在DNS服务器上,如果用户访问的DNS服务器是黑客的,然后返回的ip也是黑客预先准备好的服务器,那么用户信息就会泄露
预防DNS劫持的方法
1. 从用户的角度,防止DNS劫持
(1)手动设置DNS服务器,如果是自动的就百度一下自己的DNS ip,如果是国外的就要警惕了
(2)修改路由器Web登陆密码,不要用过于简单的密码,也能预防被入侵
(3)注意URL是否被重写了,是否是https,是否有一把小锁
2. 服务端通过流程去预防,不要想着用户有多聪明,会上面的配置,所以要加入自己的流程来预防。
流程如下(还是需要HTTPS):
(1)call API 拿到server的public key
(2)web自己gen一个16位的key1(随机数)
(3)用public来加密这个key1 -> encryptKey1(用RSA算法)
(4)前端将 encryptKey1 传给server
(5)server 通过 private key 解密 encryptKey1,拿到 key1(用RSA算法)
(6)server 自己 gen 一个16位的 key2(随机数)
(7)server 用 key1 加密 key2 -> encryptKey2 ,然后返回给前端
(8)前端用 key1 去解密 encryptKey2 ,拿到 key2(用AES算法)
(9)这样,前后端都会得到 key1 和 key2,合成一个 sessionKey
(10)数据传输时,就将数据转成 json 字符串,然后用 sessionKey 加密后请求真正的API
这个流程跟HTTPS的验证流程很相似,也存在验证效果,就是因为做多了几部验证的操作,让黑客无法猜测到如何访问服务器的API,即使入侵了用户的电脑,窃取到用户的账号密码,也无法登陆系统窃取用户钱财,是跟黑客一起讨论后得出的结果。