HTTPS (Secure Hypertext Transfer Protocol)是一个安全超文本传输协议。由于HTTP协议是一个明文传输数据的协议,对于传输某些敏感信息来说不安全,所以产生了HTTPS协议(HTTPS协议就相当于是HTTP协议的安全版本,是使用TLS/SSL加密的HTTP协议)。
HTTPS的特点:
内容加密:采用混合加密方式对发送的数据进行加密。
验证身份:通过证书来验证服务器的身份(是不是自己要访问的服务器)
保护数据的完整性:防止传输的数据被恶意篡改。
混合加密: 结合了对称加密和非对称加密技术,其中对称加密技术用于对传输数据进行加密,而非对称加密用于对协商加密技术的过程进行加密。对称加密会生成一个密钥(一个随机数),而非对称加密主要是利用一对公钥和私钥实现。
公钥和私钥:公钥和私钥就相当于钥匙和锁一样,钥匙只有一把,而锁却可以给任何人,这些人可以用锁来锁住任何信息,然后发给持有锁的人,由于锁只有一把,所以只有拿着钥匙和锁的人才知道锁的信息是什么【相当于自己把重要信息锁好之后,只让可信的人知道这些重要信息】。公钥和私钥既可以分别是锁和钥匙,也可以分别是钥匙和锁。
HTTPS加密过程:
- 客户端发起https请求
- 服务器发送证书给客户端
- 客户端解析证书
- 客户端发送密钥信息给服务器
- 服务器解析得到密钥信息
- 服务器发送加密信息
- 客户端解析加密信息
加密过程详述:
1. 客户端发起https请求
客户端在浏览器中输入一个https网址,并连接到服务器的443端口
2. 服务器发送证书给客户端
由于服务器事先会向权威的证书颁发机构(CA)申请一个证书,所以当收到客户端的HTTPS请求后,服务器会将申请到的证书发给客户端。
证书包含的内容:证书颁发机构的信息、服务器网址信息、被加密过的服务器公钥,还有经过机构私钥签名之后的数字签名(首先通过Hash函数计算服务器提交的明文信息,得出信息摘要,然后再用权威机构私钥加密这个信息摘要,加密后的密文就是数字签名),签名计算方法Hash函数以及证书对应的域名。
证书制作过程:服务器把自己的公钥、公司、站点等发给证书颁发机构,由于机构自己也有一对公钥私钥,所以该机构利用自己的私钥对服务器发来的公钥进行加密,并通过Hash函数给服务器发来的明文信息生成一个数字签名,然后也利用自己的私钥对该数字签名进行加密。
3. 客户端解析证书
由于各大浏览器和操作系统已经维护了所有权威证书机构的名称和公钥,所以客户端可以根据机构名称和对应的公钥,解析出证书信息,并通过证书中提供的签名计算方法Hash函数计算出信息摘要,然后与服务器发来的解析证书数字签名后所得的信息摘要进行对比,如果对比结果一致,表示证书有效。否则如果发现异常,则会弹出一个警告框,提示证书存在问题。
4. 客户端发送密钥信息给服务器
在对比结果一致的情况下,客户端便可以再次通过机构的公钥解析得到服务器的公钥,并利用对称加密生成一个密钥,然后利用服务器的公钥对密钥进行加密,并发送给服务器。
5. 服务器解析得到密钥信息
服务器收到客户端发来的信息之后,利用非对称加密的私钥进行解密,得到对称加密的密钥。(让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。)
6. 服务器发送加密信息
此后,由于服务器与客户端之间商量加密技术的过程已经完成,所以之后服务器与客户端之间的数据往来就是通过对称加密完成的 -> 服务器利用已经协商好的对称加密的密钥对数据进行加密发送。
7. 客户端解析加密信息
客户端在接收到服务器发来的信息后,同样利用已经协商好的对称加密的密钥对数据解密取得数据。
疑问1:为什么要对发送的数据进行加密呢?
为了防止发送的信息被第三方截获或是恶意篡改。
疑问2:既然对称加密可以对数据进行加密,那么还要非对称加密干嘛呢?
由于在通信双方对数据进行加密前,必然有一个协商加密算法和取得密钥(对称加密生成的密钥)的过程。此时由于加密算法还没定,所以协商加密算法的过程和密钥仍是明文,如果协商过程被截获,那么之后所有的加密数据对于第三方来说无疑也是明文(第三方可以利用密钥进行解密得到传输数据)。所以非对称加密就是用来对密钥的传输进行加密的。
疑问3:非对称加密是如何实现数据加密的呢?
由于非对称加密有一组公钥和私钥,明文既可以用公钥加密,私钥解密,也可以用私钥加密,公钥解密。当双方开始通信的时候,服务器先将自己的公钥发给客户端,客户端利用该公钥,对自己用于对称加密生成的密钥进行加密,并发送给服务器。当服务器收到之后,利用私钥进行解密取得对称加密密钥。在这个过程中,即使第三方一开始就截获了用公钥加密过的密钥,但是此时由于他不知道私钥,所以也解不了密。
疑问4:既然非对称加密可以实现对密钥传输的加密,那么为什么还需要数字证书呢?
当第三方截获了服务器发送给客户端的公钥之后,可能会出现第三方偷梁换柱的情况:第三方自己生成一对公钥私钥,并将自己的公钥发给客户端,此时由于客户端不知道此公钥已被篡改,所以用第三方的公钥对密钥进行了加密,并发给服务器。而此过程再次被第三方截获,并利用自己的私钥取得了密钥,然后再利用之前截获的服务器的公钥对该密钥进行加密,并将加密后的密钥发送给服务器。这样一来,即使通信双方之后的数据用密钥加密了,第三方还是可以轻轻松松对数据进行解密,而这显然没有达到我们想要的效果。那么该怎么办呢?想一下这种情况发生的本质原因: 客户端不知道自己拿到的公钥是不是自己想要访问的服务器的公钥。那么只要在客户端利用该公钥发送密钥之前,判断一下发送公钥方的身份不就可以了吗。所以服务器可以向权威的证书颁发机构申请一个数字证书,并在客户端发起https请求的时候将该数字证书发过去,让客户端进行身份验证。