前言
互联网世界中存在很对例如HTTP,FTP,webSocket等协议,而HTTP是最最常见的协议。HTTP是互联网世界中基于“请求-应答”模式,在两点之间传输例如文本,图片,音频,视频等超文本资源的约定和规范。
而在HTTPS出现之前使用HTTP进行数据传输采用的是明文传输,这种传输的弊端在于,传输过程会经过中间代理服务器,路由器,wifi热点等物理设备,攻击者会通过这些物理设备劫持传输过程中的明文内容,通过篡改明文内容攻击浏览器以及服务器,这就是我们常见的“中间人攻击”,HTTPS应运而生
什么是HTTPS
HTTPS协议是由HTTP协议基于 TLS/SSL 协议构建的可进行加密传输,身份认证的网络协议。主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据的加密传输,实现互联网传输安全保护
加密手段
- 对称加密
- 非对称加密
- 非对称加密 + 对称加密
1. 对称加密
对称加密 就是浏览器和服务器各保留一组相同的密钥,通过这个密钥对传输数据加密和解密。类似现实生活中的钥匙
如果说浏览器和服务器能够保证这组密钥的唯一性和安全性,那么浏览器和服务器之间传输加密的内容是绝对可信的。
但是(对称加密的缺点)
如果服务器生成的密钥传输给浏览器,在这个传输过程中密钥被劫持,那么加密的传输内容一样会被劫持者破解。除非浏览器内容已经预存了所有网站的密钥,但是这个是不现实的
这个时候非对称加密应运而生
2. 非对称加密
简单来讲就是,服务器生成两把钥匙,一把公钥,一把私钥,公钥的内容只能通过私钥打开,私钥内容只能通过公钥打开
对比一下上面的对称加密,我们也能够发现非对称加密中的漏洞:
1.只能保证浏览器到服务器这条传输路径上传输的数据是安全的。
因为攻击者只能劫持公钥,没法劫持私钥,因此无法解密使用公钥加密的数据
2.服务器传输数据给浏览器是不安全的
因为一旦服务器通过明文传输给浏览器的公钥被中间人劫持了,那么服务器传递给浏览器的加密数据就会被劫持
假如
- 浏览器端拥有公钥A和私钥A;服务器端拥有公钥B和私钥B。
- 浏览器将公钥A通过明文传输给服务器,服务器通过明文传输将公钥B传递给浏览器
- 那么数据从浏览器->服务器只能通过服务器的私钥B解密,服务器->浏览器的数据只能通过私钥A解密,这样就保证了数据的传输安全。
但是
非对称加密算法非常耗时,而对称加密快很对,因此HTTP加密没采用这种方式。
具体原因请参考这篇文章:zhuanlan.zhihu.com/p/164901138
!那可不可以用非对称加密的特性去改良下对称加密?????????
3. 非对称加密 + 对称加密
- 某网站拥有用于非对称加密的公钥A、私钥A。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
- 服务器拿到后用私钥A解密得到密钥X。
- 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都通过密钥X加密解密即可
通过这种方式,中间者可以劫持到公钥A,但是由于没有私钥A,因而无法劫持并解密由公钥A加密的密钥B,因而在之后的数据传输中无法劫持密钥B加密的内容。
中间人:这样的安全太菜了,还是有机可乘
如上图所示
- 服务器将公钥A传递给浏览器
- 中间人劫持到公钥A,保存下来,伪造公钥B替换原明文数据中的公钥A传递给浏览器
- 浏览器接收到公钥B,构造密钥X,通过公钥B加密密钥X和其他内容传递给服务器
- 中间人劫持公钥B,通过自己的私钥B解密传输内容,得到密钥X
- 中间人再把传输数据中的公钥B替换成公钥A,传递给服务器
- 服务器通过私钥A解密传输数据,得到密钥X
最后,大家又得到了对称加密缺陷的结果,浏览器,中间人,服务器同时拿到密钥X
浏览器此时发出一阵阵叹息,那要怎么样做,才能不被第三方知道我和服务器之间交谈的内容?
这里最重要的问题就在于,浏览器根本就不知道手中的公钥是否来自服务器
如何证明浏览器收到的公钥一定来自于正确网站的公钥?
数字证书:我来!!!!
数字证书有国际认证权威机构CA颁发,数组证书好比是一张身份证,代表网站与权威机构的关系(个人与国家的关系)有了这个身份证明,就表示是合法的,唯一的,安全的。
下面让我们来采访下CA机构
问:数字证书是什么?
网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等
问:既然这么权威,那么它是如何做到这么权威而不会被篡改的?
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名
问:数字签名怎么制作?
- CA机构拥有非对称加密的私钥和公钥。
- CA机构对证书明文数据T进行hash。
- 对hash后的值用私钥加密,得到数字签名S
问:那这个数字签名发给服务器后跟浏览器有啥关系?
- 服务器将证书发送给浏览器,浏览器拿到证书,得到明文T,签名S。
- 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S'。
- 用证书里指明的hash算法对明文T进行hash得到T'。
- 显然通过以上步骤,T'应当等于S',除非明文或签名被篡改。所以此时比较S'是否等于T',等于则表明证书可信。
问:那中间有可能在服务器向浏览器传输证书的过程中篡改证书吗?
我们打个比方
- 中间人篡改了证书原文。
- 由于其没有CA机构的私钥,所以无法得到对证书原文hash之后加密的签名,从而无法修改签名;
- 此时浏览器会发现被篡改的证书内容与签名不一致,由此说明证书不一致,从而终止与服务器传输数据。
- 因此SSL或TLS握手一定会在TCP握手之前完成
问:那中间人可能把证书掉包吗
- 假设另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息
- 此时网站B作为中间人拦截A传给浏览器的证书,然后替换成自己的证书和签名,这样浏览器就会错误的拿到B证书中的公钥。
- 但是这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了
问:为什么制作数字签名需要hash一次
因为非对称加密效率较差,而证书的信息一般较长,比较耗时,而hash后得到的是固定长度的信息(例如md5算法hash后得到固定长度的128位值),这样加解密就快很多
问:怎么证明CA机构的公钥是可信的
浏览器和操作系统本身会预装一些他们信任的根证书,如果其中有CA机构的根证书,这样就可以拿到它对应的可信公钥了
而我们在访问互联网中经常会遇到网站A信任网站B,网站B信任网站C,网站C信任网站D,这种信任的链路我们一般叫做信任链,通过这条信任链,各个网站在CA的根信任证书下进行层层互信,可以满足各个网站之间的合作需要
最后一个问题:每次进行HTTPS请求时都必须在SSL/TLS通道中传输密钥吗?
这个是不会的,第一次HTTPS请求握手建立连接时
服务器会为每个浏览器软件维护一个session ID,在TLS或SSL握手阶段传给浏览器,浏览器生成好密钥传递给服务器,服务器会把该密钥存到对应session ID下,之后每次请求会携带session ID,服务器会根据session ID找到相应的密钥进行加密解密的操作,这样就不需要每次重新制作,传输密钥了