互联网|万字长文拿下HTTPS,面试不再慌!( 八 )


互联网|万字长文拿下HTTPS,面试不再慌!
本文插图
可以看到客户端发送给服务端他所支持的密码套件有 16 套之多 , 另外客户端使用的 TLS 版本是 1.2 。

服务器收到 Client Hello 后 , 会返回一个 Server Hello 消息 。 把版本号对一下 , 也给出一个随机数(Server Random) 。
然后从客户端的列表里选一个作为本次通信使用的密码套件 。 在这里它选择了 Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 。

互联网|万字长文拿下HTTPS,面试不再慌!
本文插图
然后服务器为了证明自己的身份 , 就把证书也发给了客户端(Server Certificate) 。

接下来是一个关键的操作 , 因为服务器选择了 ECDHE 算法 , 所以它会在证书后发送 Server Key Exchange 消息 , 里面是椭圆曲线的公钥(Server Params) , 用来实现密钥交换算法 , 再加上自己的私钥签名认证 。
Handshake Protocol: Server Key Exchange
EC Diffie-Hellman Server Params
Curve Type: named_curve (0x03)
Named Curve: x25519 (0x001d)
Pubkey: 3b39deaf00217894e...
Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
Signature: 37141adac38ea4...
这相当于说:刚才我选的密码套件有点复杂 , 所以再给你个算法的参数 , 和刚才的随机数一样有用别丢了 。 为了防止别人冒充 , 我又盖了个章 。
之后是 Server Hello Done 消息 , 服务器说:我的信息就是这些 , 打招呼完毕 。
这样第一个消息往返就结束了(两个 TCP 包) , 结果是客户端和服务器通过明文共享了三个信息:Client Random、Server Random 和 Server Params 。
客户端这时也拿到了服务器的证书 , 那这个证书是不是真实有效的呢?下面客户端就开始鉴定证书的真伪 。 校验过程如下:

①首先读取证书所有者有效期等信息进行校验 , 查找内置的收信人证书发布机构 CA 与证书 CA 相对比 , 校验是否是合法机构颁发 。
这一步会做如下操作:
证书链的可信性 (trusted certificate path)校验 , 发行服务器证书的 CA 是否可靠 。
证书是否吊销 (revocation) , 有两类方式离线 CRL 与在线 OCSP , 不同的客户端行为会不同 。
有效期 (expiry date) , 证书是否在有效时间范围 。
域名 (domain) , 核查证书域名是否与当前的访问域名匹配 , 匹配规则后续分析 。
②第一步检验通过之后产生随机数 Pre-master , 并用证书公钥加密 , 发送给服务器 , 作为以后对称加密的密钥 。
客户端向服务器发送 Client Key Exchange 。 最后客户端与服务器互发 Change Cipher Spec , Encrypted Handshake Message:
互联网|万字长文拿下HTTPS,面试不再慌!
本文插图
接下来服务器接收到客户端发送的 Pre-master , 解密出被加密的 Pre-master , 然后通知客户端:握手阶段结束 , 随后所有的通信将使用对称加密的方式进行 。

双向认证
上面已经讲完了 TLS 握手 , 从上面的流程不难看出只是客户端认证了服务器的身份 , 而服务器是没有认证客户端身份的 , 我们简称单向认证 。

通常单向认证通过后已经建立了安全通信 , 用账号、密码等简单的手段就能够确认用户的真实身份 。
但为了防止账号、密码被盗 , 有的时候(比如网上银行)还会使用 U 盾给用户颁发客户端证书 , 实现双向认证 , 这样会更加安全 。
双向认证的流程也没有太多变化 , 只是在 Server Hello Done 之后 , Client Key Exchange 之前 , 客户端要发送 Client Certificate 消息 , 服务器收到后也把证书链走一遍 , 验证客户端的身份 。


推荐阅读