文章目录
Https建立链接整体示意图
HTTPS建立过程相当复杂,下图为示意图,可以有整体认识。
准备工作(对应图中prepare1234)
可以看到,在客户端向服务器发起请求前,还有一些准备工作要做,或者说是有一些工作已经做好了。
从CA证书颁发机构,获取数字证书。
- 服务器:生成一对公私钥S.pub,S.pri,私钥自己保留,用于解密和签名,不能外泄。将公钥S.pub,身份信息,传给CA(Certificate Authority)机构;
- CA机构:也有公私钥C.pub,C.pri;由S.pub,身份信息另外附加CA签名生成数字证书(签名使用C.pri进行签名)
- 将数字证书颁发给申请者(服务器)
- 客户端(比如我们经常使用的浏览器),为了安全性,会内置一份CA根证书,它包含C.pri,用于对数字证书验证
建立链接
https使用的是443端口,而http使用的是80端口
TCP端口号是一个2字节的整型,处于TCP报文段的前四个字节(2字节源端口号,2字节目的端口号)。
很明显范围是0~65535。其中0~1023具有特殊意义,已经被绑定,比如上面说的443,80,还有ftp的21端口。
下面的过程为具体详细一点的过程,如果不想看,可以完全只看示意图即可。
1 客户端发起请求(对应图中1)
同样需要三次握手,建立TCP连接(毫无疑问HTTPS也是基于TCP的)
2 客户端发送Client Hello包(对应图中2)
-
随机数
里面有1970年1月1日到现在的秒数,后面还有一个客户端发来的随机数Client.random -
Session ID
如果客户端与服务器费尽周折建立了一个HTTPS链接,刚建完就断了,也太可惜,所以用Session ID将其保存,如果下次再来可以直接使用之前的链接进行对话(对称密钥)。 -
密文族
告诉服务器,自己支持的加密算法种类 -
Server_name
3 Server Hello(对应图中2)
- 随机数:对应服务器时间,服务器sever.random
- Seesion ID,如果客户端发给服务器的session ID在服务端有缓存,服务端会尝试使用这个session;否则服务器会启用新的并返回给客户端;
- 服务器挑选一个密文族
4 Certificate(对应图中2)
服务器终于发来我们想要的数字证书,包含了:签发机构、过期时间、主题名称、公共密钥信息、指纹信息等等
5 Server Hello Done(对应图中2)
服务器发送结束
6 客户端验证(对应图中3)
客户端从内置的CA根证书获取C.pub,对服务器发送来的数字证书进行验签,如果一致,说明证书是CA颁发的(前提是C.pub是真实的,确实是CA机构的公钥)。然后看看证书是否过期,域名是否匹配
7 生成对称密钥(对应图中4、5、6)
客户端根据之前的:Client.random + sever.random + pre-master生成对称密钥
经过S.pub加密发送给服务器,之后即可通过对称密钥进行通讯。(就是之前我们熟悉的http)
建立链接后通信
使用对称密钥通信
使用下文中得到的共享密钥进行通信,速度比建立链接使用的加密快。
Https混合加密方式
建立连接时使用的是非对称加密的私钥和公钥。
链接建立后通信的时候使用的是共享密钥加密。
共享密钥加密
链接建立后使用的加密,即通信时的加密,属于对称加密,并且没有像建立链接的诸多步骤,所以速度相对较快。
非对称加密
链接建立时使用的加密,因为三次握手、证书查询、验证签名、生成共享密钥等步骤,所以速度相对来说比较慢。具有公钥私钥的概念。
为什么要使用混合加密呢?
这是安全性和通信速度的平衡考虑。
建立链接时的加密比较复杂,加密过程比较慢,但是比较安全。
链接建立后通信时则反之,而通信的时候有希望能够尽可能块,所以使用的是共享密钥。
一种共享密钥算法
这里介绍一种共享密钥的加密算法,这在密码学属于密钥交换,实例算法为Diffie-Hellman 密钥交换,使用了数学模运算、指数运算的原理。
通信双方各自有一个密钥,比如:A的密钥是X,B的密钥是Y。
( 密 文 ) = B X m o d M (密文) = B^X mod M (密文)=BXmodM ,B和M是公开的,所有人都可以知道,X是各自私有的密钥。
( B 发 送 的 密 文 ) × ( A 持 有 的 密 钥 X ) = ( A 发 送 的 密 文 ) × ( B 持 有 的 密 钥 Y ) (B发送的密文)\times (A持有的密钥X) = (A发送的密文)\times (B持有的密钥Y) (B发送的密文)×(A持有的密钥X)=(A发送的密文)×(B持有的密钥Y)
( B Y m o d M ) × X = ( B X m o d M ) × Y (B^Y mod M)\times X=(B^X mod M) \times Y (BYmodM)×X=(BXmodM)×Y
( B Y X m o d M ) = ( B X Y m o d M ) (B^Y~^X mod M)=(B^X~^Y mod M) (BY XmodM)=(BX YmodM)
至此,双发没有发送自己的密钥,但是得到了相同的共享密钥。
非对称加密过程中的签名和证书
属于加密过程中的细节,解决需求可以不看,但是面试可能考到,毕竟越来越卷了。
证书上面示意图中已经阐述过了,这里主要写签名。证书注意的地方是 1、包含公钥,2、客户端通过内置证书验证子证书是不是合法的。
明文hash后的东西叫签名。
一句话说清楚:签名、明文、签名时使用的hash算法,这三个东西一起在客户端请求建立链接后发送给客户端,客户端把明文用hash算法计算,得出的值与传过来的签名对比,相同就没篡改。
缺点: 明文连着签名都给你伪造了。解决办法:证书。