Linux网络:HTTPS协议
在HTTP
协议中,所有的数据都采用明文的形式传输,这就会导致数据非常容易泄露,只要拿到HTTP
报文,就可以窃取各种信息。
基于HTTP
协议,使用一定的加密措施,让HTTP
内部的数据变为密文,就升级为了HTTPS
协议,其中S
表示Secure
或者Safe
,都是安全的意思。
加密方式
对称加密
对称加密是一种采用单个密钥的加密方式,通信双方采用的密钥相同,因此称为对称加密。
常见的对称加密算法有:DES
、3DES
、AES
、TDEA
这些算法是公开的,但是密钥不是公开的,只要通信双方的密钥不泄露,就算别人知道使用了哪一个算法,也无法解密密文。
比如一个简单的对称加密算法:加减法。
假设现在对数据123456
进行加密,密钥C = 6
。
- 服务端使用密钥
C
加密:
123456 - 6 = 123450
此时就得到密文123450
,将密文通过HTTP
发送给客户端。
- 客户端使用密钥
C
解密:
123450 + 6 = 123456
客户端就拿到了最终数据123456
。
假设某个黑客截取到了HTTP
报文,破解出数据为123450
,也知道使用了加减法,这个黑客可以得到原数据吗?
当然不可以,因为黑客没有密钥C
,他不知道123450
这个密文要与谁进行加法,自然得不到原数据。
以上过程只是简单了解原理,实际上不会用加减法这样简单的计算来做加密。
如果服务端与客户端通信前都约定好,使用指定的加密算法和密钥C
,那么就可以保证这个通信是安全的。
比如一个服务端与它的多个客户端都使用C
作为密钥:
但是这样有一个问题,如果任意一个客户端泄露了这个密钥C
,那么所有客户端的信息都会被泄露。因此实际上并不会对所有的客户端采用相同的密钥,而是每个客户端都使用不同的密钥。
如果每个客户端都使用不同密钥,那么就不能再提前约定了,因为服务端并不知道未来有哪些客户端要连接自己,所以在正式通信前,要为每个客户端生成一个密钥,并告知客户端。
问题来了,这个告知客户端密钥的消息是不被加密的,黑客就可以截取第一次报文,查看到这个密钥。此后虽然客户端与服务端都有密钥C
,但是黑客也有密钥C
,即使后续进行通信时数据会被加密,但是对于黑客来说和明文传输没有区别。
对称加密有以下特点:
- 简单
- 计算量小,加密速度快,效率高
非对称加密
非对称加密采用两个密钥完成:
公钥 S
:公开的密钥,任何人都可以知道这个密钥私钥 S*
:私有的密钥,只有非常少的人知道
公钥和私钥是配对的,它们一个负责加密,一个负责解密,有以下两种情况:
- 使用公钥
S
加密:
拥有公钥的用户可以加密,拥有私钥的人可以解密。而公钥是完全公开的,也就是说任何人都可以加密一个数据,发送给持有私钥的人。而私钥只有少数人持有,说明只有少数人有资格查看加密的数据。
举个例子,在校长办公室门口有一个信箱,所有学生都可以投放信件,提出建议。而提出的建议被放到信箱内部,其他人打不开信箱,就无法查看学生的建议,这样投放信件到信箱的过程,就是使用公钥加密数据的过程,任何一个人都可以加密数据。
如果想要查看信箱内部的信件,那么就必须有信箱的钥匙,而钥匙只有校长有,这个信箱钥匙就是私钥。只有校长可以看信件,也就是只有私钥持有者有资格查看数据。
- 使用私钥
S*
加密
使用私钥加密与之前是相反的过程,只有私钥的持有者有资格加密数据,但是任何人都可以查看加密后的数据。
也举个例子,这就像学校发布的告示文件,这种文件往往需要学校盖章,表示这个文件是本校发布的,具有权威性。那么这个公章就是私钥,只有持有公章的人有资格代表学校发布告示,而任何人都可以阅读这个告示。
在网络通信中,由于双方都需要收发数据,如果采用非对称加密,那么就要采用两对公钥和私钥。
假设服务端生成S S*
这对密钥,客户端生成C C*
这对密钥,采用私钥进行加密,公钥进行解密。
如果黑客截取到了密文,就算它持有两个公钥S
和C
,但是解密报文需要私钥S*
和C*
,这个只有客户端和服务端分别持有,那么黑客就无法破解数据。
每一个客户端与服务器都要维护两对密钥,那么这两对密钥就需要临时生成,在最开始需要进行公钥的交换。
最开始客户端与服务端互相不知道公钥,那么就需要互相告知自己的公钥,交换公钥的过程是不加密的,黑客就可以拿到公钥S
和C
,但是就算黑客拿到了两个公钥,它也破解不了报文。因为报文是拿公钥加密的,要拿私钥解密,而客户端与服务端之间各自生成私钥,根本没有把私钥发送到网络上,黑客就无法破解报文!
这样看起来很完美了,但是它无法抵挡中间人攻击
,这个稍后讲解。
非堆对称加密比较复杂,而且加密速度慢。
混合加密
总结以上两个加密方式:
对称加密
:效率高,如果黑客在交换密钥时入侵,加密会失效非对称加密
:效率低,如果黑客在交换密钥时入侵,加密依然有效
那么能不能结合一下两者,集合它们的优点?
在对称加密中,主要是害怕第一次交换密钥会泄露,因此第一次交换密钥需要进行一次额外的加密。问题就变成了:在对称加密交换密钥时,需要对密钥加密。
对这个对称密钥加密,不能采用对称加密的方式,必须采用非对称加密,因为非对称加密不怕交换密钥时的黑客入侵。
流程如下:
- 服务端生成非对称密钥
S
与S*
- 服务端告知客户端公钥为
S
- 客户端生成对称密钥
C
- 客户端告知服务端对称密钥为
C
,并使用公钥S
加密 - 服务端使用
S*
解密报文,得到对称密钥为C
- 后续所有通信采用对称密钥
C
这个连接过程中,只有第一个报文告知S
公钥是没有加密的,而非对称加密不怕公钥泄露。随后客户端利用这一层非对称加密,来加密密钥C
,这样就可以保证C
的安全性。
随后所有的通信都采用C
,就可以提高加密的效率,又不怕C
被泄露,这就是结合前两者的混合加密
。
不过这种加密方式也害怕中间人攻击
。
中间人攻击
中间人攻击简称MITM
,先前两种加密方式看似都很完美,但是都逃不过中间人攻击。
在进行密钥交换之前,必然要建立TCP
连接,而在建立连接的过程中,有可能会有第三者入侵。
假设当前TCP
连接建立完成,但是发生了中间人入侵。
中间人入侵后,此时server
以为middle
是客户端,client
以为middle
是服务端。
以混合加密为例,展示中间人是如何绕开加密的:
首先server
生成非对称密钥S
和S*
,并发送公钥S
给中间人(server
以为中间人是客户端):
你可能以为,公钥根本就不怕被公开,此时middle
就算拿到了公钥S
也没有任何作用。这确实没错,但是这也是中间人攻击最巧妙的一步:自己再生成一对非对称密钥M
和M*
。
客户端接收到公钥M
后,以为这是服务端发送来的消息,以为服务端的公钥是M
。
客户端生成对称密钥C
,通过公钥M
加密发送给中间人:
此时中间人通过私钥M*
解密报文,得到对称密钥为C
,于是再伪装自己是客户端,把C
利用公钥S
加密发回给服务端。
随后客户端与服务端采用C
进行加密通信:
客户端与服务端都以为自己完成了完美的加密过程,但是其实中间人早已经拿到了对称密钥C
,后续的所有报文中间人都可以轻松破解。
导致中间人攻击的源头,就是第一次交换公钥S
,客户端无法得知自己收到的公钥是来自于服务端还是中间人。
证书
由于客户端无法确定与自己通信的是否是服务端还是中间人,此时一个CA
机构站了出来,它维护了一个公钥A
和一个私钥A*
,把公钥告知给所有的浏览器。当服务器发送数据前,可以找CA
机构进行认证,生成一个证书,客户端拿到数据后,通过检验证书来得知与自己通信的是否是目标服务器。
数据签名
数据签名是一种基于非对称加密的校验方式,其可以检测出数据是否被篡改。
- 生成报文:
当发送数据时,先把数据data
使用哈希算法生成一个哈希值,在把哈希值通过私钥A*
进行加密,这样就得到了签名
。
最后发送报文时,把data
和签名
一起发送出去。
- 验证报文:
接收方从收到的报文中,解析出data
和签名
两个部分。
- 对
data
使用相同的哈希函数,得到一个哈希值 - 使用公钥
A
对签名解密,得到另一个哈希值 - 对比两个哈希值
依据哈希算法的特性,如果两个数据的哈希值不同,那么这两个数据一定不同。因此只要数据被篡改,那么此处两个哈希值就不同。
那么在加密过程中,到底哪一步需要通过数据签名进行确认?就是第一步:服务端给客户端发送公钥时,将自己的公钥,域名等信息一起打包作为数据data
,并进行签名发送给客户端。
此时如果发生中间人攻击,中间人如果替换了公钥,那么就会造成data
与原先不一致,进而导致哈希值不同,客户端就知道有中间人的存在了。
CA认证
将域名,公钥等信息进行打包得到data
,在加上这个data
的签名,就是一个证书
,也就是说证书 = 服务端信息 + 签名
。
证书由CA
机构进行颁发,用于保证证书的权威性。先前说过,CA
机构会自己维护一个私钥A*
,不透露给任何人,并且所有浏览器都会内置对应的公钥A
。
服务器配置HTTPS
协议前,要想CA
机构申请证书,服务器先生成非对称密钥S
和S*
,并把这些信息打包发送给CA
机构。CA
机构会对这些信息进行确认,如果验证通过,就利用哈希函数和私钥A*
对这个数据生成签名,并把签名和服务端信息打包成证书,发送给服务端。
后续服务端再与客户端通信,只需要把证书发给客户端。由于浏览器内置了公钥A
,客户端就可以检测签名是否正确,域名是否是目标域名,从而确认该公钥确实来自于服务器,随后执行混合加密过程,生成对称密钥C
,完成真正的加密通信。
基于这种CA
认证的方式,中间人就无法对证书进行修改或者掉包。
- 中间人修改证书
如果中间人修改了证书中的公钥S
,将其变为自己的公钥M
,此时签名就无法匹配修改后的数据,客户端就得知证书被修改了。
- 中间人掉包证书
如果中间人想要掉包证书,那么就要保证自己证书中的签名可以被A
解密,那么中间人就需要持有A*
,但是A*
被CA
机构严格维护,中间人得不到。
中间人也可以向CA
机构申请证书完成掉包,但是申请证书需要同时提交域名和公钥。
- 中间人使用服务端的域名,配上自己的公钥
M
申请证书,CA
机构会进行审核,发现匹配不上,不会给中间人颁发证书 - 中间人拿自己的域名,配上自己的公钥
M
申请证书,虽然可以得到证书,但是客户端拿到掉包的证书后,发现域名不是自己目标服务器的域名,就可以知道证书被掉包了
HTTPS
先前的内容,只是HTTPS
的基本原理,也就是使用混合加密 + 证书
的模式,实际上HTTPS
的流程还要稍微复杂一点,不过基于前面的内容也很好理解了。
SSL/TSL
HTTPS
的加密部分,是由SSL/TSL
协议完成的,具体关系在下一个小标题会讲解。
先前的混合加密 + 证书
的模式中,对称密钥C
完全由客户端生成,服务端完全没有参与这个过程,而在真正的SSL/TSL
协议中,这个对称密钥是由双方进行协商得出的。
HTTPS
通信流程:
首先,客户端要与服务端建立TCP
连接,随后正式开始HTTPS
协议。
- 客户端发送一个
Client Random
随机数,这个随机数与后文的密钥相关,并发送一些其它的客户端本身的信息 - 服务端返回一个
Server Random
随机数,也与后文的密钥相关 - 服务端发送自己的证书
- 服务端发送一个密钥交换算法,以及这个算法的一些相关参数
- 发送
Hello Done
报文,表示结束
这个密钥交换算法有很多种,此处为ECDHE
算法。
- 正式开始加密:
客户端首先验证证书的可靠性,在这个证书中包含服务端的公钥S
。随后给服务端也发送一个ECDHE
的参数,并且这个报文由S
公钥进行加密。
此处不对ECDHE
算法深入了解,只需要知道客户端与服务端会交换这个算法的部分参数。
当客户端与服务端拿到了ECDHE
算法的参数,以及两个随机数Client Random
和Server Random
,就开始正式生成密钥。
- 双方分别基于
ECDHE
算法,生成预主密钥Pre-Master
,由于先前已经交换过参数,它们计算出的值是相同的 - 双方分别基于
Client Random
和Server Random
,对预主密钥Pre-Master
进行再次计算,得到主密钥master secret
这个主密钥master secret
又会进一步生成会话密钥session secret
。
随后客户端发送Change Clipher Spec
报文,表示接下来的报文将使用会话密钥session secret
加密。随后立刻发送Fished
报文,这个报文也会被session secret
加密,在这个报文内部,包含了客户端之前各种信息形成的哈希值。
服务端ACK
确认该报文后,正式开始通信,当服务端第一次发送数据之前,也会发送发送Change Clipher Spec
报文,表示接下来的报文将使用会话密钥session secret
加密,再发送一个Fished
报文,也包含了服务端之前各种信息生成的哈希值。
当双方的Finded
报文都发送完毕后,就可以互相知道对方的哈希值,从而对比出之前是否有数据不统一,如果这两个哈希值一样,那么生成的session secret
就是一样的。
最后正式开始HTTPS
通信。
- 总结
在以上过程中,麻烦的是双方要互相交换很多数据,最终的sesson secret
密钥,是一个对称密钥,但是这个密钥是由双方一起决定的,不再是客户端独自生成。
如果忽略复杂的密钥生成过程,可以直接简化为最初的混合加密 + 证书
的模型,最后还是维护了一个对称密钥实现数据加密。只不过这个经过这个生成密钥的过程,最终的对称密钥安全性更高。
此处得到对称密钥的方式有很多种,本博客只是讲解了其中一种ECDHE
,也没有细讲该算法内部的具体内容。
HTTPS
HTTP
、HTTPS
、SSL
、TLS
协议关系如下:
其实HTTPS
协议就是在HTTP
协议基础上增加了一个加密层,而加密是由SSL
或TLS
实现的,其中SSL
是TLS
的前身。
所以上一个小标题叫做SSL/TLS
,这表示加密部分是由这两个协议实现的,并且两者是or
的关系。
原文地址:https://blog.csdn.net/fsdfafsdsd/article/details/143833068
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!