"这一封信只是得到它要回答问题,那个答案早已点燃在心里"
紧接上文这仍然是一款拙劣的http服务器,我们此时在用户数输入栏输入数据信息并提交表单。我们先来认识认识使用到的两个工具软件。
postman是一款支持http协议的接口调试与测试工具,其主要特点就是功能强大,使用简单且易用性好。
Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据。
我们通过抓包工具,能够很轻易地将用户数据捕获。
我们看到这两个工具 都能够发送http报头和接收远端响应的http报文,那么它们两者的区别在于什么呢?
两者都是测试接口工具。
但是Fiddler更像是一个代理服务器,它会捕获本地浏览器访问远端服务器的报头信息,并转发,而PostMan拥有自己的Post、Get方法请求,能够模拟和浏览器一样的行为,直接向远端服务器发起http请求。
话说回来,发送的报头信息被截获,我们能够看到用户输入的真实数据。这正常吗?正常!因为http本来就是明文传输,可是将用户数据如此暴露在网路环境中,并且轻易能被抓包工具窃取或监听其中的信息,这是不安全的,且不能容忍的!
受到劫持时,我们源下载被替换成了QQ浏览器! 由于我们通过⽹络传输的任何的数据包都会经过运营商的⽹络设备(路由器,交换机等),那么运营商的⽹络设备就可以解析出你传输的数据内容,并进⾏篡改。当然,不止是数据明文传过运营商会被劫持或者修改。这些明⽂数据会经过路由器、wifi热点、通信服务运营商、代理服务器等多个物理节点,每一个节点都可能出现被劫持的情况。
当然,不仅仅是运营商可以进行劫持,其他的⿊客也可以⽤类似的⼿段进⾏劫持,来窃取⽤⼾隐私信息,或者篡改内容。让Client和Sever都没法察觉双方的通信是否已经被劫持或者受到监听。
这也叫做,"中间人攻击" 。
因此,在互联网中,明文传输是很危险的事情 !
HTTPS 也是⼀个应⽤层协议. 是在 HTTP 协议的基础上引⼊了⼀个加密层。而Http协议的内容是按照文本的明文方式传输,当数据在网路中进行传输时,可能会发生泄漏甚至是被篡改的情况!
我们站在 " 四层网络模型来看 ":
可以看出,http\https都是应用层上的协议。但是如何区别一个请求报头是基于https还是http协议? 实际上是根据port端口号来进行区别。
80: http 默认端口号
443: https 默认端口号
到了https这里,数据传输就不再是 "明文传输",而是给传输的数据加了一层 "密文"。
因此,在https在网络中根本不是传输的原始数据,而是通过 "加密"过后的密文 ,此时本地和对端各自持有一把 "秘钥",能对 "加密"后的数据进行解密拿到原始数据,从而让 没有持有 "秘钥"的中间人,既是监听获取到 密文,而束手无策。
对称加密:
采⽤ “单钥密码系统” 的加密⽅法,同⼀个密钥可以同时⽤作信息的加密和解密,这种加密⽅法称为对称加密,也称为单密钥加密,特征:加密和解密所⽤的密钥是相同的。
常⻅对称加密算法:
DES、3DES、AES、TDEA、Blowfish、RC2等
特点:
算法公开、计算量⼩、加密解密速度快、加密效率⾼。
非对称加密:
采用两个密钥来进⾏加密和解密,这两个密钥是公开密钥(publickey,简称公钥)和私有密钥(privatekey,简称私钥)。
常⻅⾮对称加密算法(了解):
RSA,DSA,ECDSA
特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,⽽使得加密解密速度没有对称加密解密的速度快。
其中,公钥与私钥可以互相对着用:
①• 通过公钥对明⽂加密,变成密⽂
• 通过私钥对密⽂解密,变成明⽂
②• 通过私钥对明⽂加密,变成密⽂
• 通过公钥对密⽂解密,变成明⽂
数据摘要&&数据指纹:
数字指纹(数据摘要),其基本原理是利⽤单向散列函数(Hash函数)对信息进⾏运算,⽣成⼀串固定⻓度的数字摘要。数字指纹并不是⼀种加密机制,但可以⽤来判断数据有没有被窜改。摘要常⻅算法:
有MD5、SHA1、SHA256、SHA512等,算法把⽆限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率⾮常低)。
同加密不同,数据摘要不是严格的加密方式,因为它不具有解密这样的逆过程。摘要通常不是用来比对原数据怎样,因为这很难反推原数据信息,而是用来 进行 “数据比对” !
我们在来看看如下网盘的例子,一个网盘 不会存储多个用户的相同资源,毕竟本质一种资源浪费。
一个数据库管理员,直接通过查表的方式,就能得到用户真实的数据查询出来也是尚且不妥的。
上述图片是对mysql中用户数据的查询,它 本质上就是一个 通过一些算法形成的 ”数据摘要”。
数字签名:
将原始数据形成的摘要,进行特殊算法进行加密,就形成了数字签名。
回归本篇的集中探讨的问题: 为什么需要https?emmm...因为http是明文传输的,已经验证过明文传输对于一些用户的隐私数据而言,这无疑是 “裸奔”,是不安全的。而解决网络传输中不安全的问题,无非致力于 两个问题:
① 数据被监听
② 数据被篡改
唔,你说的我都懂,上面也说了https拥有对称加密,非对称加密等等方式,保障用户数据在从传输过程中的安全性。可是怎么加密的呢?双方的过程又是 怎样的呢?
并且一个极其重要的问题,要进行正常加密通信之前,你总得保证通信双方都能安全获取秘钥吧~
唔,这很好,客户端与服务器在建立连接时,Client就从Server端 获取秘钥,并对数据进行加密并之后进行传输。 正因为黑客 压根不知道服务端的秘钥是什么,所以,它无法对加密的数据进行解密!很好地保护了用户数据的传输过程。
但事实真的是这么简单嘛?
你可别忘了,中间人是贯穿通信过程的始终的。服务端向客户端发送 "秘钥信息时",它是不是明文呢? 是的!那么它需不需要进行加密传输? 是的!这也就成了,“先有鸡还是先有蛋”的问题。否则,如果将秘钥信息进行明文传输,黑客 也十分欢心地轻易拿到秘钥,这所谓的 加密过程,也就形同虚设。
鉴于⾮对称加密的机制,让服务器先把 "公钥" 以明⽂⽅式传输给 客户端,之后 "客户端" 向服务器传数据前,都先⽤这个 "公钥加密" 好再传,因为中间人是没有"私钥",因此无法破解加密后的传输数据。因此客⼾端到服务器的传输 "是安全的" (这里只是暂时这么认为!!!)。
可是,现在你又如何保证 "服务端" 到 "客户端" 的传输安全呢? 你显然不能荒唐到传私钥给客户端,以便让客户端可以解密公钥加密的内容,因为那样做,中间人也可以拿到私钥了,之前做的努力全都付诸东流……
为解决这个问题,你忽然脑袋瓜子一拍,并很高兴地分析这其中的可行性。
1.服务端拥有公钥S与对应的私钥S',客⼾端拥有公钥C与对应的私钥C'
2.客⼾和服务端交换公钥
3.客⼾端给服务端发信息:先⽤S对数据加密,再发送,只能由服务器解密,因为只有服务器有私钥S'
4.服务端给客⼾端发信息:先⽤C对数据加密,在发送,只能由客⼾端解密,因为只有客⼾端有私钥C'
这可行嘛?答案是当然不行。首先从效率上就吃太多亏了!本来非对称性加密的效率就低于对称加密,而你倒好,直接让双方都使用非对称加密。况且,一个服务器显然不是只为你一台主机服务,势必也有会其他更多的主机需要这种 双方交互的非对称公钥,服务器需要维护这众多的关系……这是个很⿇烦的事情~
和上述的方案一样,这里也只是暂时认为它安全。但实际它是不安全的~
我们首先着眼于解决效率问题。
1. 服务端具有⾮对称公钥S和私钥S',客⼾端发起https请求,获取服务端公钥S。
2. 客⼾端在本地⽣成对称密钥C,并通过公钥S加密,发送给服务器。
3. 服务器通过私钥S'解密,还原出客⼾端发送的对称密钥C.并且使⽤这个对称密钥加密给客⼾端返回的响应数据.
由于中间的⽹络设备没有私钥,即使截获了数据,也⽆法还原出内部的原⽂,也就⽆法获取到对称密钥。服务器通过私钥P'解密,还原出客⼾端发送的对称密钥C.并且使⽤这个对称密钥加密给客⼾端返回的响应数据。后续客⼾端和服务器的通信都只⽤对称加密即可.由于该密钥只有客⼾端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义。
emmm到现在看来,效率得到了一定的提升,并且通过非对称加密的方式,保障了对称秘钥在明文传输过程中的安全。现在效率得到了一定的提升,并且通过非对称加密的方式,保障了对称秘钥在明文传输过程中的安全。
可是真的是这样嘛? 中间人如果截获数据,因为没有秘钥而无法还原出原始报文的真实数据嘛?其实上述的几个方案,共同都忽略了一个问题,那就是 "中间人贯穿通信过程的始终"。它完完全全不会等到你 那么轻松地完成秘钥的交换!
Man-in-the-MiddleAttack,简称“MITM攻击”。对于非对称+对称的方式进行加密传输,如果中间人在它们握手协商时就进行攻击,那么就会很简单获取双方各自的秘钥信息。
服务器具有⾮对称加密算法的公钥P,私钥P`。
中间⼈具有⾮对称加密算法的公钥MP,私钥MP`。中间⼈劫持数据报⽂,提取公钥S并保存好,然后将被劫持报⽂中的公钥S替换成为⾃⼰的公钥M,并将伪造报⽂发给客⼾端。
客户端用拿到被篡改过的公钥MP,加密自己的对称秘钥C。
中间⼈劫持后,直接⽤⾃⼰的私钥MP`进⾏解密,得到通信秘钥C,再⽤曾经保存的服务端公钥P用拿到的对称秘钥C加密后,将报⽂推送给服务器。
服务器拿到报⽂,⽤⾃⼰的私钥P'解密,得到通信秘钥C。
双⽅开始采⽤X进⾏对称加密,进⾏通信。但是⼀切都在中间⼈的掌握中,劫持数据,进⾏窃听甚⾄修改,都是可以的。
此时,一波偷梁换柱,直接让通信双方在不察觉的情况下,正快快乐乐地认为安全、高效的通信,实际上是被监听着的!实际上是已经被替换、篡改过的!
这怎么解决呢?答案是 现目前是结局不了的!当然 也并非放任不管!
上述方案看似能够进行“安全地”通信,但最终结果可能事与愿违,其本质在于什么呢?
"客⼾端⽆法确定收到的含有公钥的数据报⽂,就是⽬标服务器发送过来的~",换句话说解决方案应该围绕: " 客户端如何识别服务端发过来的 合法的公钥! "。
CA(Certificate Authority,证书授权)是由认证机构服务者签发,是数字签名的技术基础保障,也是网上实体身份的证明,能够证明某一实体的身份及其公钥的合法性,证明该实体与公钥二者之间的匹配关系。 取自这里
服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有 "证书申请者信息、公钥信息" 等等 。
当客户端登录浏览器,访问服务器时,服务器会把该CA证书传输给浏览器,客户端只需要从证书⾥获取公钥就⾏了。证书就如⾝份证,证明服务端公钥的权威性。
需要注意的是:申请证书的时候,需要在特定平台⽣成查,会同时⽣成⼀对⼉密钥对⼉,即公钥和私钥。
这对密钥对⼉就是⽤来在⽹络通信中进⾏明⽂加密以及数字签名的。
其中公钥会随着CSR⽂件,⼀起发给CA进⾏权威认证,私钥服务端⾃⼰保留,⽤来后续进⾏通信(其实主要就是⽤来交换对称秘钥)。
秘钥文件
要理解CA证书的认证策略,其根本在于理解 "数据签名"。
此时,中间人攻击无非就致力于两头,一个是对 明文信息 进行篡改,一个是对 数据签名进行篡改!
因此,中间人无法对局部数据做出任何更改,无论是明文信息,还是数据签名!
而数据签名的本质作用就在于, " 防止 明文信息被篡改!”。如何防止的呢? CA机构有自己的私钥!
下面以一些提问的方式,来作为本篇文章的结束。
• 中间⼈篡改了证书的明⽂,客⼾端收到该证书后会发现 "明⽂" 摘要和 "签名"解密后形成的摘要两者值不⼀致时,则说明证书已被篡改,该证书不可信,从⽽终⽌向服务器传输信息,防⽌信息泄露给中间⼈。
• 由于他没有CA机构的私钥,所以⽆法 "在hash之后⽤私钥" 加密形成 "签名",那么也就没法办法对篡改后的证书形成匹配的签名。
• 因为中间⼈没有CA私钥,所以⽆法制作假的证书。
• 所以中间⼈只能向CA申请真证书,然后⽤⾃⼰申请的证书进⾏掉包。然而,真的证书会需要 完善的认证信息,没有哪一个黑客想这些信息被暴露。
• 永远记住:中间⼈没有CA私钥,所以对任何证书都⽆法进⾏合法修改,包括⾃⼰的。
常⻅的摘要算法有:MD5和SHA系列。摘要算法的过程是不可逆的,但是两个相同的内容进行摘要,得到的值一定是相同的!只要其中有一点点值不一样,摘要出来的内容差别会很大。例如,证书一旦有内容被篡改,摘要过后的值,一定和解密签名时的摘要 大相径庭。
数据摘要(数据指纹)的本质就是缩小密文长度,形成一个固定长短的字符串,加快加密的运算效率。
这个就是完整的一套https加密通信的过程: CA证书 + 非对称秘钥 + 对称秘钥
本篇就到此结束,感谢你的阅读。
祝你好运,向阳而生~