公钥基础设施(三):SSL协议

本篇主要讲SSL协议的通信过程。

几个小问题

SSL协议是干什么的?

首先,SSL是一种Web安全机制,他的作用是加密双方通信保证双方在不安全网络上的信息私密且不被篡改。

SSL是怎么加密通信的?

简单来说,双方先使用公钥体制互相验证身份并协商一个密钥,然后双方使用这个密钥作为之后通信的对称密钥来加密会话。
由于协商密钥是使用公钥体制进行的,所以密钥本身是不会被其他人截获的,所以保证了之后的通信过程加密的可靠性。
而之后的会话使用对称密钥是因为每次都使用非对称密钥则开销过大,使用对称密钥可以大大节省开销。

SSL协议详解

体系结构

有人说,SSL是在TCP和HTTP层之间的,也有人说,SSL层是和HTTP层并列在TCP层之上的。
我觉得应该是这样的:

SSL记录协议

记录协议将要发送的数据分块、压缩(可选)、加上消息认证代码(MAC)、加密、再加上一个SSL头,将最终的到的数据放入一个TCP段。
一个SSL记录的格式如下图所示:

SSL修改密码规范协议和警报协议

这两个协议对我们开发来说关系不大。
修改密码规范协议仅一个字节,值为1,用于更新连接所使用的的密码套件。
警报协议两个字节,第一个字节表示等级,1表示警报(warning),2表示致命错误(error),第二个字节是警报信息的描述码,这里不详细列举。

SSL握手协议

这是SSL协议的重点,SSL的复杂性和安全性基本依赖于握手协议。

握手协议一共分四个阶段:

第一阶段:建立安全功能

第一阶段的主要任务是协商SSL版本、加密算法、压缩算法等。具体流程如下:

客户端发出一个ClientHello,包括

  • 客户端可以支持的SSL最高版本号
  • 客户端生成的一个随机数
  • 会话ID
  • 客户端可以支持的密码套件列表
  • 客户端可以支持的压缩算法列表

那么服务器返回一个ServerHello,包括

  • 确定使用的SSL版本号(取客户端和服务器支持的最高版本号的较小值)
  • 服务端生成的一个随机数
  • 会话ID
  • 服务端确定使用的密码套件
  • 服务端确定使用的压缩算法

至此,客户端服务端已经协商确认了:

  • SSL版本
  • 密钥交换、信息验证和加密算法
  • 压缩方法
  • 有关密钥生成的两个随机数
第二阶段:服务器认证和密钥交换

第二阶段双方之间做的事主要就是,服务器向客户端发送相关信息。
一般先后发送四条消息:

  • 证书链
  • 服务器密钥交换
    • 此阶段非必须,以下情况下不需要此消息
      • 服务器发送了带有固定Diffie-Hellman参数的证书
      • 使用RSA密钥交换
    • 那么剩下的,以下情况需要此消息
      • 匿名Diffie-Hellman:消息内容包括两个全局Diffie-Hellman值和服务器Diffie-Hellman公钥
      • 瞬时Diffie-Hellman:消息内容包括三个Diffie-Hellman参数,包括匿名Diffie-Hellman中的两个参数和它们的签名
      • RSA密钥交换,服务器在使用RSA时仅使用了RSA签名密钥:因此,客户端不能简单地通过服务器公钥加密其密钥后传送,而服务器必须创建一个临时RSA公钥/私钥对,并使用服务器密钥交换信息发送公钥。消息内容包括两个临时的RSA公钥参数和参数签名。
      • Fortezza
    • 注:此时的签名并不是直接将请求hash后用私钥加密。为了防止重放攻击,还会将上一阶段客户端和服务器生成的两个随机数带上一起hash。
  • 证书请求消息(服务器不使用匿名Diffie-Hellman)
    • 包含两个参数:证书类型和签证机构
      • 第一个参数证书类型表明了公钥算法和用途
      • 第二个参数签证机构是一张可接受的签证机构表
  • 服务器完成消息(没有其他内容,仅表示消息结束)
第三阶段:客户端认证和密钥交换

第三阶段是客户端向服务器发送信息的阶段。在此之前,客户端会先检验服务端证书的有效性、参数是否可接受。
一般先后有三条消息:

  • 证书链(可选,如果服务器请求了证书,那么需要发送证书消息,如果没有证书需要发送“无证书警报”)
  • 客户端密钥交换消息
    • 消息的内容依赖密钥交换的类型:
      • RSA:客户端生成48字节的次密钥,并使用服务器证书中的公钥或服务器密钥交换消息中的临时RSA密钥加密。他被用于生成主密钥
      • 瞬时或匿名Diffie-Hellman:发送的客户端Diffie-Hellman公钥参数
      • 固定Diffie-Hellman:由于证书消息中包括Diffie-Hellman公钥参数,因此此消息内容为空
      • Fortezza:发送客户端的Fortezza参数
  • 证书验证消息
    • 固定Diffie-Hellman不发送这一消息
    • 客户端用私钥签名主密钥和握手信息,以防客户证书被盗用
第四阶段:完成

此阶段完成安全连接的设置。
过程如下:

  • 客户端使用修改密码规范协议发送一个修改密码规范消息(切换为对称加密)
  • 客户端使用新的加密算法和密钥发送一个完成消息,完成消息的内容是对握手消息的hash,确认密钥交换和认证过程的正确性
  • 服务端回应一个修改密码规范消息
  • 服务端使用新的加密算法和密钥发送一个完成消息

至此,握手完成,客户端和服务器可以用对称加密交换信息了。
至于主密钥的计算由于和我们关系不大,我们只需要知道是用次密钥、服务器随机数、客户端随机数这三者生成的就可以了。有兴趣的小伙伴可以自行查阅相关书籍或资料。