了解过http协议的可能知道其中主要使用的两种请求方法中,PSOT比GET方
法更具有安全性,但是要我说:POST方法和GET方法都不安全,硬要说的话
只能说POST方法比GET方法更具有私密性,因为GET方法会把它请求的资
源暴露在url上,而POST的请求资源的路径会放在http请求报文中的请求消息
中,所以你在网页上登录时,如果使用的是GET方法,你的账号密码会直接
暴露在搜索栏上,而使用POST方法不会,但是这样就安全了吗?这其实不是
的,因为像这种情况,只需要一个抓包工具在你的网络上的节点上抓你的http
请求,那么你的账号密码也是暴露了。所以如果你的数据在没有被加密的情
况,是没有什么安全性可言的,那么基于http协议的不安全的情况,就有了
HTTPS。
1. HTTPS的简单认识
时至今日,我们在浏览器上访问的网站基本上都是HTTPS协议而不是HTTP,那么HTTPS是什么呢?它其实就是在HTTP的协议上对协议报文中的消息体做了加密,而它与HTTP的关系可以这么理解:
也就是HTTP与HTTPS的区别就是在向下层交付的时候,HTTPS报文比HTTP报文多了一层加密的过程,那么我们认识HTTPS就是主要认识这一层加密的细节,当然我们并不是要研究人家的加密算法,而是HTTPS是如何保证它在网络传输过程中是安全的。
2. 名词的铺垫
a. 明文/密文
在正式研究HTTPS如何保证它的报文安全之前,我们有必要了解在加密解密领域的一些名词,以及这些名词的含义:
我在上面说HTTPS其实就是HTTP报文加了一层加密层,那么我们把加密之前的内容就成为明文 ,加密之后的叫做密文 , 而在加密过程中所使用到的数据就叫做密钥。
b. 加密方式
现在主要的两种加密方式就是对称加密 和非对称加密:
1). 对称加密
对称加密就是明文到密文的加密和密文到明文的解密都是使用的同一个密钥,比较简单理解的对称加密就是对明文或者密文进行按位异或同一个数字以达到加密和解密:
对称加密的加密密钥和解密密钥是同一个,对称加密的优点就是:计算量小,加密解密速度快,效率高。
2). 非对称加密
在非对称加密中,会有两个密钥,一个是私钥 一个是公钥 ,对于公钥加密后的密文来说,只能由对应的私钥来解密,而经过私钥加密过的密文来说,只能由对应的公钥来解密。一般来说,私钥是需要自己保管,且不能对外界暴露的,而公钥要对外界进行暴露,这一点通过它们的名字也可以看出来。
但是非对称加密的缺点就是:效率低下,解密加密时间长。
3). 数据摘要&&数据指纹
还有一种技术,但是这种技术不能算是加密技术了,因为它无法进行对密文解密,那就是对明文数据进行哈希散列成为一个固定长度的字符串,这个字符串会随着明文内容的不同而不同,也就是明文数据中有一丁点的改动,这个通过哈希散列成的字符串就会不相同,通过这样的方式,我们可以使用这个字符串来对比历史数据是否被修改过,或者使用这个字符串可以快速检索到我们想要的资源。
比较常见的应用场景就是,服务器端的用户的密码等隐私数据都将他们变成数据指纹,这样的用户登陆的时候,我们可以对用户的密码进行同样的哈希算法,然后与历史的数据指纹做对比,就可以决定用户是否可以登陆了。这样的话,就算服务端数据库数据泄露,得到这些数据的人也不能利用数据库中的数据造成进一步损失。
3. HTTPS加密
基于上面对一些名词的认识,我们现在就可以开始认识HTTPS协议是如何保证数据的安全性的,但是我在这里不直接说明解决方式,而是采用层层递进的方式,让我们感受到HTTPS是如何一步步完善它的。
a. 对称加密
我们可以对HTTP报文进行对称加密:
我们将我们要使用的密钥内置到客户端,然后就可以实现双方的加密传输了,但是这样的设计是有缺陷的,那就是客户端有很多个,但是它们使用的密钥都是同一个,这样的话,很容易就让黑客通过截获大量报文对密钥进行破解。
有人说,那我们不可以在客户端和服务器连接的时候,让服务端动态生成一个密钥不就可以了?这样更是有缺陷因为你开始给客户端发送的携带密钥的报文是否加密?如何加密?所以这是一个未加密的报文,那么黑客也会得到这个密钥。
b. 非对称加密
那我们现在来使用非对称加密:
这样我们好像只能保证单向的安全通信,那么就有人说了两端都使用非对称加密不就可以了。
b. 双方都使用非对称加密
这样的方式貌似保证了双方都能进行安全的通信(其实,这种和上面的b方式都不安全),但是这种方式有个最大缺陷,那就是非对称加密的加密解密的效率很低 。
所以就有了第四种解决方式:
d. 非对称加密+对称加密
我们先使用非对称加密将客户端生成的对称密钥作为信息传递给服务器,此时中间人是无法获取到这个对称密钥的,那么以后客户端和服务器就可以使用这个对称密钥进行安全的通信了,但是这种方式和上面两种方式一样,仍存在安全问题,在上面的中间人攻击时,都是等双方交换公钥密钥之后才开始攻击,但是如果我们从一开始就攻击这个连接呢?
这样的流程下来,中间人就得到了双方安全通信所使用的对称密钥,那么双方的通信也就不再安全了。
e. 证书
在上面的第四种方法时,我们可以看到:其中的核心问题就是,客户端无法识别它收到的公钥是谁的。所以我们的第五个方法就是解决这个问题,而它就是证书。
1). 证书是什么?
在我们使用浏览器的时候我们或许会遇到这样的问题:
那么这个证书到底是什么呢?我们先来看一下证书的结构:
首先,这个证书由两部分构成,一部分就是明文信息:
明文信息中主要包含了该网站建立的机构、组织或者个人的相关信息,证书的有效期,最重要的它会携带,申请证书的的机构提供的一个公钥S。
然后根据这些基本信息,证书颁发机构会根据明文信息形成数据指纹也就是签名,至此我们就可以根据这个签名来判断明文信息是否被修改过。
那这个证书是如何解决我们开始的问题呢?我们得先要了解证书的颁发过程:
2). 证书申请颁发过程
首先,网站建立者会建立自己的一对私钥和公钥,然后又会添加自己的一些实名信息,网站域名,自己的公钥生成.csr文件,然后将这个文件交给CA认证机构,这个CA认证机构是一个非常权威的一个机构,在它那一方面我们认为不会出问题。
然后CA认证机构就会对你提交的信息进行审核(审核过程非常严格),审核成功之后,CA认证机构就会将明文信息形成数据指纹也就是签名,然后再使用CA机构自己的私钥(这个私钥,全世界只有CA认证机构拥有)将签名加密。
最后将明文信息和加密后的签名一起发给申请证书的申请者。
3). 证书验证
那么我们如何使用这个证书呢?
当客户端访问服务器时,首先服务端就会将自己的证书发给客户端,客户端收到这个证书之后就会将证书中的明文信息使用和CA认证机构一样的哈希函数,形成签名,然后客户端浏览器会使用CA机构的公钥来将密文签名进行解密,然后对比两个签名,来判断自己收到的是否是服务端发来的公钥:
这就是CA证书的大致使用流程,看完上图之后,很多人或许就有点迷糊,这样就能保证中间人得不到这个密钥C了?
我们现在就来分析一下:
我们在d方式中的核心问题就是无法判断自己收到的公钥是谁发送来的。
我们假如作为中间人,我们截获到服务端发给客户端的CA证书之后:
我们将其中的明文信息进行修改,将其中的公钥改成自己的,这样CA证书到了客户端之后,客户端对证书进行检验,发现两个散列值不一样,客户端不会用用这个公钥。
我们假如对CA证书的签名进行修改,首先这么做是没有意义的,我们的目的是获取到双端进行通信时使用的密钥,修改了签名之后,CA证书到客户端之后,CA机构的公钥无法对这个签名密文进行解密,客户端也不会使用这个公钥,其次,就算CA机构的公钥能解密这个签名密文,揭秘之后的散列值也不会跟明文信息形成的散列值相等。客户端还是不会使用这个公钥。
假如同时修改明文信息和签名密文,让最后的散列值相等,且明文信息中的公钥是自己的,这么一句话下来,这不就是相当于中间人自己去申请CA认证了吗?申请的时候使用的是服务器的域名,这合理吗?不合理,因为域名已经被占用了。就算申请成功,中间人也暴露了自己的实名信息,得不偿失。
所以我们的第五种方法就是使用证书+对称密钥+非对称密钥的方式来确保两端主机在网络通信过程中是安全的,不会暴露信息。
4). 遗留问题
在上面我们知道了HTTPS是如何确保安全的网络通信之后,关于证书其实还有三个隐藏的小问题:那就是.csr文件是什么?怎么形成.csr文件?
其实现在我们可以在浏览器上就可以找到生成.csr文件的网站,我们就可以输入我们要交给CA机构的身份信息然后,然后就可以帮我们生成对应的.csr文件了:
还有就是当客户端向服务器开始发起请求获取到网站的CA证书之后需要对CA证书进行验证,而验证的其中的一个条件就是需要CA认机构的公钥,那么这个公钥在哪里呢?其实也不难想到,CA机构的公钥早就在我们安装浏览器的时候,浏览器已经内置了CA机构的公钥,那么它们在哪里呢?以谷歌浏览器为例:
当然,有些人的游览器中有很多的公钥,这是因为CA机构可以有很多,比如北京有北京的CA机构,上海有上海的CA机构,并且有一些机构是属于被CA机构认证过的受信机构,都可以颁发CA证书,所以就会存在浏览器中存在多个CA机构的公钥。
以上就是HTTPS协议保证两端主机网络通信时的安全的演变过程。