SSL/TLS协议的基本过程

是这样的 [1]:

客户端向服务器端索要并验证公钥
双方协商生成"对话密钥"
双方采用"对话密钥"进行加密通信
// 前两步,又称为"握手阶段"(handshake)
// "握手阶段"的所有通信都是明文的
../../../_images/protocol_ssl_tls_handshake1.png

1.客户端发出请求(ClientHello):

客户端主要向服务器提供以下信息:
1.支持的协议版本,比如TLS 1.0版
2.一个客户端生成的「随机数1」,稍后用于生成"对话密钥"
3,支持的加密方法,比如RSA公钥加密
4.支持的压缩方法
//这里需要注意的是,客户端发送的信息之中不包括服务器的域名
//也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书
//这就是为什么通常一台服务器只能有一张数字证书的原因
//2006年,TLS协议加入了一个Server Name Indication扩展,允许客户端向服务器提供它所请求的域名
@add
支持的最高TLS协议版本,随机数、密码算法列表及压缩方法

2.服务器回应(SeverHello):

1.确认使用的加密通信协议版本,比如TLS 1.0版本
//如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
2.一个服务器生成的「随机数2」,稍后用于生成"对话密钥"
3.确认使用的加密方法,比如RSA公钥加密
4.服务器证书
@add
服务器回复ServerHello消息,包含:
  基于客户端ClientHello消息所选择的TLS协议版本,随机数、密码算法列表及压缩方法
当双方知道了连接参数,服务器向客户端发送证书

3.客户端回应:

//客户端收到服务器回应以后,首先验证服务器证书
//a.如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期
//就会向访问者显示一个警告,由其选择是否还要继续通信
//b.如果证书没有问题,客户端就会从证书中取出服务器的公钥
//然后,向服务器发送下面三项信息:
1.一个「随机数3」。该随机数用服务器公钥加密,防止被窃听
2.编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
3.客户端握手结束通知,表示客户端的握手阶段已经结束
  这一项同时也是前面发送的所有内容的hash值,用来供服务器校验
//这儿的「随机数3」,又称"pre-master key"
//如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息
@add
客户端验证服务器证书的合法性,包括:
  服务器证书是否过期、发行服务器证书的CA是否可靠、
  发行CA的公钥能否正确解开服务器证书的发行CA的数字签名、
  服务器证书上的域名是否和服务器的实际域名相匹配
  如果
    1. 合法性验证没有通过,通讯将断开
    2. 合法性验证通过
客户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥对其加密
  然后将加密后的“预主密码”传给服务器
[可选]如果服务器要求客户端的身份认证:
  客户端可以建立一个随机数然后对其进行数据签名,
  将这个含有签名的随机数和客户端自己的证书以及加密过的“预主密码”一起传给服务器

4.服务器的最后回应:

//服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"
//然后,向客户端最后发送下面信息:
1.编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
2.服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
@add
[可选]如果服务器要求客户端的身份认证,服务器必须检验客户端证书和签名随机数的合法性,合法性验证包括:
a.客户端证书是否过期
b.发行客户端证书的CA是否可靠
c.发行CA的公钥能否正确解开客户端证书的发行CA的数字签名
d.检查客户端证书是否在证书废止列表(CRL)中
如果
  1.合法性验证没有通过,通讯立刻中断
  2.如果合法性验证通过,服务器将用自己的私钥解开加密的“预主密码”
    然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)

5.至此,整个握手阶段全部结束:

接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容
[1]SSL/TLS协议运行机制的概述