https握手

HTTPS

SSL握手过程 图解SSL/TLS协议
ssl握手过程

  1. 用户发起一个请求到服务器,浏览器将自己支持的一套加密机制发送给服务器,生成随机数。
  2. 服务器从中选一套加密算法和hash算法,并将自己的身份信息以证书的形式发送给客户端,证书包括网站域名,加密公钥(客户端需要用这个加密)以及证书的颁发机构等,并生成随机数
  3. 客户端获取到证书信息后:
    1. 浏览器验证证书是否合法,主要验证证书的域名与网站地址是否一致,颁发机构是否合法等,如果证书合法,则浏览器上会出现一个,否则会有一个警告弹出,当然用户可以选择继续信任证书。
    2. 浏览器生成一串新的随机数密码并用证书中提供的公钥加密(非对称加密),用约定好的hash算法计算握手信息,并用生成的随机密码对握手消息进行加密(对称加密),发送给服务器。
  4. 服务器接受到请求后:
    1. 用私钥解密获取消息随机数密码,然后用密码解密握手消息,用hash算法来验证消息是否一致,确定是来自当期会话。
    2. 用密码加密握手消息发送客户端
  5. 客户端使用密码解密握手消息,并用hash算法计算消息是否一致,如果一致此时握手结束,从此客户端与服务器通信都采用对话密码密(前面生成的三个随机数生成的对话密钥)对称加密所有通信数据。
这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。另外,HTTPS一般使用的加密与HASH算法如下:
非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,RC4,3DES
HASH算法:MD5,SHA1,SHA256

其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。

SSL/TLS握手过程可以分成两种类型:

  1. SSL/TLS 双向认证,就是双方都会互相认证,也就是两者之间将会交换证书。
  2. SSL/TLS 单向认证,客户端会认证服务器端身份,而服务器端不会去对客户端身份进行验证。
我们知道,握手过程实际上就是通信双方协商交换一个用于对称加密的密钥的过程,而且握手过程是明文的。
这个过程实际上产生三个随机数:client random, server random, pre-master secret.

前两个随机数都是明文传送的,只有pre-master secret是加密的(RSA或者DH)。
一般生成证书的时候,签名算法可以选择RSA或者DSA算法。
如果server使用RSA证书,RSA即可以用作签名也可以用作不对称加密,pre-master secret就是用server的RSA证书中包含的公钥加密的。
如果server使用DSA证书,DSA只能用作签名,所以还需要使用DH算法来交换密钥。

以下是其流程图:

1. ServerKeyExchange,CertificateRequest,Certificate,CertifiateVerify
是可选的。
2. 如果是单向认证,CertificateRequest,Certificate,CertifiateVerify。
3. ServerKeyExchange这一步只有在选择了某些密钥交换算法例如DH算法的时候才需要。

image

以下是抓包(单向认证,www.zhihu.com)请求:
[图片上传失败...(image-ebf417-1563421558970)]

Client Hello

1. SSL Version 信息.
2. 客户端支持的加密套件(Support Ciphers)
3. 生成随机数 Client Random(用于生成对话密钥).
image

Server Hello

1. 确认使用的协议版本
2. 服务端生成的随机数Server Random,(至此客户端和服务端都拥有了两个随机数(Client Random + Server Random),这两个随机数会在后续生成对称秘钥时用到。)
3. 确定加密一份套件
4. session id (session id的思想很简单,就是每一次对话都有一个编号(session id)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的"对话密钥",而不必重新生成一把。)
image

Certificate

发送证书给客户端,客户端验证自己的身份,客户端验证通过后取出证书中的公钥。
image

Server Key Exchange

如果是DH算法,这里发送服务器使用的DH参数。RSA算法不需要这一步。
image

certificate_request

服务端要求客户端上报证书,包括
1. 客户端可以提供的证书类型
2. 服务器接受的证书distinguished name列表,可以是root CA或者subordinate CA。如果服务器配置了trust keystore, 这里会列出所有在trust keystore中的证书的distinguished name。

Server Hello Done

服务端通知客户端hello done


image

Certificate Verify

客户端收到服务端传来的证书后,先从 CA 验证该证书的合法性,验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3 生成 pre-master secret。

Client Key Exchange

1. 客户端生成Random3(如果是采用RSA算法,会生成一个48字节随机数,然后用server的公钥加密之后再放入报文中;如果是DH算法,这里发送的就是客户端的DH参数,之后服务器和客户端根据DH算法,各自计算出相同的pre-master secret)。
image

Change Cipher Spec(Client)

客户端通知服务器开始使用加密方式发送报文。客户端使用上面的3个随机数(Client Random, Server Random, pre-master secret)计算出48字节的pre-master-key,这个就是对称加密算法的密钥。

Encrypted Handshake Message(Client)

客户端发送第一个加密报文。使用HMAC算法计算收到和发送的所有握手消息的摘要,然后通过RFC5246中定义的一个伪函数PRF计算出结果,加密后发送。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。

Change Cipher Spec(Server)

服务端通知客户端后面再发送的消息都会使用加密,用私钥解密出密码,根据前面三个随机数用约定好的算法生成对话秘要,然后计算报文比对一致则通过。

Encrypted Handshake Message(Server)

这一步对应的是 Server Finish 消息(服务器握手结束通知),服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。
image

Application Data

到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输。

至于为什么一定要用三个随机数,来生成"会话密钥"?

不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。

你可能感兴趣的:(https握手)