Defined | |
---|---|
Protocol | Year |
SSL 1.0 | n/a |
SSL 2.0 | 1995 |
SSL 3.0 | 1996 |
TLS 1.0 | 1999 |
TLS 1.1 | 2006 |
TLS 1.2 | 2008 |
TLS 1.3 | TBD |
1、客户端发送 ClientHello 消息,包括 最高支持的 TLS 协议版本,随机数,加密套件,压缩算法。如果希望下次重用握手,可以包含 session id。如果客户端使用 ALPN,可以包括应用层的协议列表,比如http2
2、服务器回一个 SeverHello 消息,包括选择的协议版本,随机数,选择的加密套件和压缩算法。服务器确认或者允许重用握手可能需要发送一个 session id。选择的协议版本应该是客户端和服务端都支持的最高版本
3、服务端发送 Certificate 消息
4、服务器发送 ServerKeyExchange 消息,使用RSA进行密钥交换无需交换任何临时参数,所以可以没有 ServerKeyExchange 阶段,
5、服务器发送 ServerHelloDone 消息,表示握手协议完成
6、客户端生成 PreMasterSecret 并用服务器的公钥加密,回应 ClientKeyExchange 消息,包括 PreMasterSecret,可能包括客户端的公钥。
7、客户端和服务端利用两个随机数和 PreMasterSecret 生成 master secret,也就是接下来使用的对称秘钥(Session Key)
8、客户端发送 ChangeCipherSpec 告诉对方接下来所有的消息都是经过加密的
9、最后客户端发送加密的 Finished 消息,并且包含 MAC。服务器解密并且验证 MAC,如果解密或者验证失败,握手失败
10、服务端发送 ChangeCipherSpec 告诉对方接下来所有的消息都是经过加密的
11、服务端发送加密的 Finished 消息,客户端解密并验证
12、握手完成
一般现在Web服务器的架构是Nginx+OpenSSL(假设是),Nginx只支持单机多进程间共享的Session Cache,所以为了可靠性一般需要有全局的分布式Session Cache,这样就能保证在多台Web服务器之间共享使用Session ID。
Session Cache 的方案需要在服务器做缓存,会导致服务端需要较大的内存。
Kx 为 RSA 时候,Au 也必须为 RSA,且可以省略
RSA:由client生成 premaster secrete,用 server 的公钥加密后在 ClientKeyExchange 包中传给 server,server再用自己的私钥解密。RSA秘钥的长度,至少应大于2048位才是安全的,较长的秘钥使得RSA解密一个256位的 premaster secrete 需要2ms左右,比较消耗服务端CPU资源。
ECDHE (Elliptic Curve Diffie–Hellman Exchange) = ECC + DH + E,是在DH算法的基础上,加入了椭圆曲线算法,使得所需秘钥的长度变短,最后的E表示每次动态生成参数和key,其中参数使用了证书中公钥对应的私钥进行了签名。
因为使用了RSA 2048位的私钥进行签名,参数签名后长度变成了256字节。如果使用密钥为256位的ECDSA证书,则只需32个字节。
client 使用动态参数、自己的临时私钥和server的临时公钥来生成一个premaster secret。
server 使用动态参数、自己的临时私钥和client的临时公钥(在ClientKeyExchange包中传出)生成相同的premaster secret。
ECDHE 算法有更短的密钥,能更快地得到对称加密的密钥,相比RSA消耗更少的服务端CPU资源。而且搭配ECDSA证书会有更好的效果。