SSL_TLS相关内容梳理

证书文件格式说明:

  • .key:私钥文件,通常使用rsa算法,私钥需要自己保存,无需提交给ca机构
  • .crt:证书文件,certificate的缩写
  • .csr:证书签名请求(证书请求文件),含有公钥信息
  • .crl:证书吊销列表
  • .pem:用于导出,导入证书时候的证书格式,是.key和.crt的合体

Q:什么是数字签名,有什么作用?

作用:验证消息的来源,以及证明消息是否被篡改

签名:用私钥对消息的哈希值进行加密称为签名,只有拥有私钥的用户可以生成签名

生成签名的步骤:

  1. 对消息进行哈希计算,得到哈希值
  2. 利用私钥对哈希值进行加密,生成签名
  3. 将签名附加在消息后面,一起发送过去

验证签名:用公钥解密签名这一步称为验证签名,所有用户都可以验证签名(因为公钥是公开的)

验证签名的步骤:

  1. 收到消息后,提取消息中的签名
  2. 用公钥对签名进行解密,得到哈希值1
  3. 对消息中的正文进行哈希计算,得到哈希值2
  4. 比较哈希值1和哈希值2,如果相同,则验证成功

Q:什么是证书,如何验证证书?

证书:实际上就是公钥的数字签名,是对公钥合法性提供证明的技术。它包括公钥本身,公钥的数字签名,公钥拥有者的信息等等。

生成证书的步骤:

  1. 服务器将公钥A给CA(公钥是服务器的)
  2. CA用自己的私钥B给公钥A加密,生成数字签名A
  3. CA把公钥A,数字签名A,附加一些服务器信息整合在一起,生成证书,发回给服务器

注:私钥B是用于加密公钥A的,私钥B和公钥A并不是配对的

验证证书的数字签名需要另一个公钥,保证这个公钥的合法性则需要第三方认证机构,即CA。CA能够认定公钥确实属于此人,并能生成公钥的数字签名。CA有国际性组织和政府设立的组织,也有通过提供认证服务来盈利的组织。

验证证书的步骤:

  1. 客户端得到证书
  2. 客户端得到证书的公钥B(通过CA或其他途径)
  3. 客户端用公钥B对证书中的数字签名解密,得到哈希值
  4. 客户端对公钥进行哈希计算
  5. 两个哈希值对比,如果相同,则证书合法

注:公钥B和上述的私钥B是配对的,分别用于对证书的验证(解密)和生成(加密)

另外,当用户私钥丢失,被盗时,认证机构需要对证书进行作废。要作废证书,认证机构需要制作一张证书作废清单(Certificate Revocation List),检查CRL。我们在验证证书的合法性时,除了验证其是否在有效期内,还需要查询其CRL,确认证书是否有效。

Q:单向认证 & 双向认证 & 不认证

  • 单向认证:指的是只有一个对象校验对端的整数合法性,通常是客户端来校验服务器的合法性。那么client需要一个ca.crt,服务端需要server.crt、server.key,当然也可以是服务端校验客户端。
  • 双向认证:指的是相互校验,服务器需要校验每个client证书,client也需要校验服务器证书
  • 不认证:指的是不相互校验证书,但仍然使用TLS连接

    Q:单向认证流程?

  1. client_hello:客户端发起请求,以明文传输请求信息,包含版本信息,加密套件候选列表,压缩算法候选列表,随机数,扩展字段等信息
  2. server_hello + server_certificate + server_hello_done
    1. server_hello,服务端返回协商的信息结果,包括选择使用的协议版本version,选择的加密套件cipher suite,选择的压缩算法compression method、随机数random_S等,其中随机数用于后续的密钥协商
    2. server_certificates,服务端配置对应的证书链,用于身份验证与密钥交换
    3. server_hello_done,通知客户端server_hello信息发送结束
  3. 证书校验
    1. 证书/证书链的可信性
    2. 证书是否吊销revocation,有两类方式离线CRL与在线OCSP,不同客户端行为不同
    3. 有效期expire date,证书是否在有效时间范围
    4. 域名damain,检查证书域名是否与当前的访问域名匹配(CN字段)
  4. client_key_exchange + change_cipher_spec + encrypted_handshake_message
    1. client_key_exchange:合法性验证通过之后,客户端计算产生随机数字pre-master,并用证书公钥加密,发送给服务器
    2. 此时客户端已经获取全部的计算协商密钥需要的信息:两个明文随机数random_C和random_S与自己计算产生的pre-master,计算得到协商密钥enc_key=Func(...)
    3. change_cipher_spec:客户端通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信
    4. encrypted_handshake_message:结合之前所有通信参数的hash值与其他相关信息生成一段数据,采用协商密钥session secret与算法进行加密,然后发送给服务器用于数据与握手验证
  5. change_cipher_spec + encrypted_handshake_message
    1. 服务器用私钥解密加密的pre-master数据,基于之前交换的两个明文随机数random_C和random_S,计算得到协商密钥enc_key=Func(...)
    2. 计算之前所有接收信息的哈希值,然后解密客户端发送的change_cipher_spec以告知客户端后续的通信都采用协商的密钥与算法进行加密通信
    3. change_cipher_spec,验证通过之后,服务器同样发送change_cipher_spec以告知客户端后续的通信都采用协商的密钥与算法进行加密通信
    4. encrypted_handshake_message,服务器也结合所有当前的通信参数信息生成一段数据并采用协商密钥session secret与算法加密并发送到客户端
  6. 握手结束:客户端计算所有接收信息的哈希值,并采用协商密钥解密encrypted_handshake_message,验证服务器发送的数据和密钥,验证通过则握手完成
  7. 加密通信:开始使用协商密钥与算法进行加密通信