传输安全HTTPS

科技资讯 投稿 5300 0 评论

传输安全HTTPS

为什么要有 HTTPS

    通信的消息会被窃取,无法保证机密性(保密性):由于 HTTP 是 “明文” 传输,整个通信过程完全透明,其他人能够窃取到传输的明文信息。
  • 通信的消息会被篡改,无法保证完整性:使用 HTTP 通信,任何人都能够在通信的过程中截获并篡改请求报文、响应报文,但消息接收者无法识别报文是否被篡改。
  • 通信的消息会被伪造,无法确认消息发送者的真实身份(身份认证):使用 HTTP 通信,任何人都能够给一个接收者发送消息,但是消息接收者无法确认消息发送者的真实身份。也就是说,无法进行身份认证。
  • 无法保证不可否认性(不可抵赖):使用 HTTP 通信,消息接收者收到一个消息后,通信的一方可以否认(抵赖)消息不是他发送的。也就是说,消息接收者无法证明这一消息的确是由通信的一方发送的。

只有同时具备了机密性、完整性、身份认证、不可否认这四个特性,才能算得上是安全的通信。

介绍 SSL/TLS

SSL 即安全套接层(Secure Sockets Layer)。

至今,TLS 已经发展出了三个版本,分别是 2006 年的 1.1、2008 年的 1.2 和 2018 的 1.3,每个新版本都紧跟密码学的发展和互联网的现状,持续强化安全和性能。目前应用最广泛的 TLS 版本是 1.2,而之前的版本(TLS1.1 / 1.0、SSLv3 / v2)都已经被认为是不安全的。


TLS 由记录协议、握手协议、警报协议、变更密码规范协议、扩展协议等几个子协议组成:

    记录协议(Record Protocol)规定了 TLS 收发数据的基本单位是:记录(record)。它有点像是 TCP 里的 segment,所有其他的子协议都需要通过记录协议发出。多个记录数据可以在一个 TCP 包里一次性发出。
  • 握手协议(Handshake Protocol)是 TLS 里最复杂的子协议。通信的双方在 TLS 握手的过程中协商 TLS 的版本号、密码套件,交换随机数、数字证书和密钥参数,最终通信的双方协商得到会话密钥。
  • 警报协议(Alert Protocol)的职责是向对方发出警报信息。收到警报的一方可以选择继续连接,也可以立即终止连接。它有点像是 HTTP 里的状态码,比如 protocol_version 就是不支持旧版本,bad_certificate 就是证书有问题。
  • 变更密码规范协议(Change Cipher Spec Protocol)就是一个“通知”,告诉对方:后续传输的都是对称密钥加密的密文。也就是说,“Change Cipher Spec” 消息之前传输的都是明文,之后传输的都是对称密钥加密的密文。

TLS 的密钥套件

TLS 的密码套件命名非常规范。固定的格式是:“密钥交换算法 + 签名算法 + 对称加密算法 + 分组模式 + 消息摘要算法”,例如 “ECDHE-RSA-AES256-GCM-SHA384” 密码套件的意思就是:

    密钥交换算法使用的是:ECDHE。通信的双方在 TLS 握手的过程中协商 TLS 的版本号、密码套件,交换随机数、数字证书和密钥参数,通信的双方使用 ECDHE 算法算法 "Pre Master Secret"。

  • 签名算法使用的是:RSA。TLS 握手的过程中,使用 RSA 签名算法进行数字签名。服务器给浏览器发送 "Server Key Exchange" 消息,服务器对密钥参数(消息中的 Public 参数)进行数字签名,然后把签名值一并发送给浏览器。浏览器收到 "Server Key Exchange" 消息后,使用数字证书中的公钥对密钥参数(消息中的 Public 参数)进行验签。

  • 对称加密算法使用的是:AES-256。TLS 握手后的通信使用 AES 对称加密算法进行加密,以实现机密性。对称密钥的长度 256 位

  • 分组模式使用的是:GCM。加密明文的长度不固定,而一次对称加密只能处理特定长度的一块数据,这就需要进行迭代,以便将一段很长的数据全部加密,而迭代的方法就是分组模式。

  • 消息摘要算法使用的是:SHA-384。TLS 握手的过程中,两次用到了该消息摘要算法。一次是:“PRF” 通过消息摘要算法,根据三个随机数(Client Random、Server Random 和 Pre Master Secret)计算主密钥 "Master Secret" 的值。另一次是:通信的双方给对方发送 "Finished" 消息。一方对之前发送的数据做摘要,再使用会话密钥对摘要进行对称加密,让对方进行验证(类似数字签名的验签)。TLS 握手后的通信使用该消息摘要算法进行消息认证,防止消息被篡改。

TLS1.2 握手的过程

执行 TLS 握手的目的是:通信的双方安全的协商会话密钥。会话密钥用于 HTTP 报文的加解密,以实现机密性。


下面说的是使用 ECDHE 算法实现密钥交换的 TLS 握手过程。

    浏览器给服务器发送 "Client Hello" 消息,服务器给浏览器发送 "Server Hello" 消息。通信的双方协商 TLS 的版本号、密码套件,并交换随机数。
  • 交换数字证书:服务器为了向浏览器证明自己的身份,服务器给浏览器发送 "server Certificate" 消息,以发送数字证书链,其中包含了两个证书。一个是 CA 机构颁发的数字证书,另一个是 CA 机构的数字证书。
  • 服务器给浏览器发送 "Server Key Exchange" 消息,浏览器给服务器发送 "Client Key Exchange" 消息。通信的双方交换密钥参数(Client Params 和 Server Params),然后通信的双方使用 ECDHE 算法算出 "Pre Master Secret"。
  • 通信的双方根据自己已知的参数(Client Random、Server Random 和 Pre Master Secret)算出主密钥 "Master Secret",并使用主密钥拓展出更多的密钥(会话密钥),避免只用一个密钥带来的安全隐患。
  • 浏览器给服务器发送 "Change Cipher Spec" 消息,服务器也给浏览器发送 "Change Cipher Spec" 消息。告诉对方:后续传输的都是对称密钥加密的密文。
  • 浏览器给服务器发送 "Finished" 消息,服务器也给浏览器发送 "Finished" 消息。通信的双方把之前发送的数据做摘要,再使用会话密钥对摘要进行对称加密,让对方进行验证(类似数字签名的验签)。
  • 双方都验证成功,握手正式结束,之后就可以正常收发被加密的 HTTP 请求和响应了。

TLS 握手的过程如下图所示,其中每一个框都是一个记录,多个记录组合成一个 TCP 包发送。所以,最多经过两次消息往返(4 个消息,或者说 4 个 TCP 包)就可以完成 TLS 握手。

第一个消息往返

    Version:TLS 的版本号
  • Random:浏览器生成的随机数(Client Random)。随机数用于后续生成主密钥
  • Cipher Suites:浏览器支持的密码套件
Handshake Protocol: Client Hello
    Version: TLS 1.2 (0x0303
    Random: 1cbf803321fd2623408dfe…
    Cipher Suites (17 suites
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f
        Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030

服务器收到浏览器发送的 "Client Hello" 消息后,服务器给浏览器发送 "Server Hello" 消息。"Server Hello" 消息携带几个参数:Version、Random、Cipher Suite。

    Version:TLS 的版本号
  • Random:服务器生成的随机数(Server Random)。随机数用于后续生成主密钥
  • Cipher Suite:服务器选择使用的密码套件(服务器从浏览器发送的 "Client Hello" 消息的 Cipher Suites 参数中选)
Handshake Protocol: Server Hello
    Version: TLS 1.2 (0x0303
    Random: 0e6320f21bae50842e96…
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030

服务器为了向浏览器证明自己的身份,服务器给浏览器发送一个证书链,包含了两个证书。一个是 CA 机构颁发的数字证书,另一个是 CA 机构的数字证书。


服务器给浏览器发送 "Server Key Exchange" 消息。"Server Key Exchange" 消息携带几个参数:Curve Type、Named Curve、Pubkey、Signature Algorithm、Signature。

    Curve Type、Named Curve:使用的椭圆曲线的类型
  • Pubkey:根据【服务端的椭圆曲线的私钥】和 基点 G 计算出的【服务端的椭圆曲线的公钥】(Server Params),用于后续计算 “Pre Master Secret”
  • Signature Algorithm、Signature:使用的签名算法、签名值
Handshake Protocol: Server Key Exchange
    EC Diffie-Hellman Server Params
        Curve Type: named_curve (0x03
        Named Curve: x25519 (0x001d
        Pubkey: 3b39deaf00217894e...
        Signature Algorithm: rsa_pkcs1_sha512 (0x0601
        Signature: 37141adac38ea4...

服务器给浏览器发送 "Server Key Exchange" 消息之后,服务器发送信息完毕。服务器给浏览器发送 "Server Hello Done" 消息,服务器向浏览器说明:服务器发送信息完毕了。

验证数字证书

浏览器收到服务器发送的数字证书之后,浏览器需要验证数字证书是否合法、有效。

浏览器确认了服务器的身份之后,就开始了第二个消息往返。

第二个消息往返

Handshake Protocol: Client Key Exchange
    EC Diffie-Hellman Client Params
        Pubkey: 8c674d0e08dc27b5eaa…

至此,通信的双方都获取到了 ECDHE 密钥交换算法需要的两个参数(Client Params、Server Params),于是通信的双方就使用 ECDHE 算法算出一个随机数,这个随机数被叫做 "Pre Master Secret"。

目前,通信的双方已知三个随机数:Client Random、Server Random 和 Pre Master Secret。通信的双方使用这三个随机数作为原始信息,通过 PRF 算出主密钥(Master Secret)。因为黑客拿不到 "Pre Master Secret",所以黑客也就无法得到主密钥。

master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random

主密钥的长度为 48 字节,但是主密钥并不是最终用于通信的会话密钥,还会再用 PRF 扩展出更多的密钥,比如浏览器发送用的会话密钥(client_write_key)、服务器发送用的会话密钥(server_write_key)等,避免只用一个密钥带来的安全隐患。有了主密钥和派生的会话密钥,TLS 握手就快结束了。


服务器也进行和浏览器同样的操作。

    服务器给浏览器发送 "Change Cipher Spec" 消息。服务器告诉浏览器:服务器后续传输的都是对称密钥加密的密文。
  • 服务器给浏览器发送 "Finished" 消息。浏览器对之前发送的数据做摘要,再使用会话密钥对摘要进行对称加密,让浏览器进行验证。

使用 RSA 的 TLS 握手

TLS1.2 握手可以划分为两种方式:使用 RSA 算法实现钥交换 和 使用 ECDHE 算法实现密钥交换。

TLS 握手过程的简要描述:通信的双方在 TLS 握手的过程中协商 TLS 的版本号、密码套件,交换随机数、数字证书和密钥参数,最终通信的双方协商得到会话密钥。"Hello" 消息交换随机数,"Key Exchange" 消息交换 "Pre Master Secret"。

    浏览器给服务器发送 "Client Hello" 消息,服务器给浏览器发送 "Server Hello" 消息。通信的双方协商 TLS 的版本号、密码套件,并交换随机数。
  • 交换数字证书:服务器为了向浏览器证明自己的身份,服务器给浏览器发送 "server Certificate" 消息,以发送数字证书链,其中包含了两个证书。一个是 CA 机构颁发的数字证书,另一个是 CA 机构的数字证书。
  • 服务器给浏览器发送 "Server Hello Done" 消息,服务器向浏览器说明:服务器发送信息完毕了。
  • 浏览器验证数字证书合法、有效后,获取数字证书中【服务器的公钥】。浏览器生成随机数 "Pre Master Secret",使用【服务器的公钥】对生成的 "Pre Master Secret" 进行加密。然后,浏览器给服务器发送 "Client Key Exchange" 消息,把加密后的 "Pre Master Secret" 发送给服务器。
  • 服务器收到浏览器发送的 "Client Key Exchange" 消息后,使用【服务器的私钥】解密出随机数 "Pre Master Secret"。
  • 通信的双方根据自己已知的参数(Client Random、Server Random 和 Pre Master Secret)算出主密钥 "Master Secret",并使用主密钥拓展出更多的密钥(会话密钥),避免只用一个密钥带来的安全隐患。
  • 浏览器给服务器发送 "Change Cipher Spec" 消息,服务器也给浏览器发送 "Change Cipher Spec" 消息。告诉对方:后续传输的都是对称密钥加密的密文。
  • 浏览器给服务器发送 "Finished" 消息,服务器也给浏览器发送 "Finished" 消息。通信的双方把之前发送的数据做摘要,再使用会话密钥对摘要进行对称加密,让对方进行验证(类似数字签名的验签)。
  • 双方都验证成功,握手正式结束,之后就可以正常收发被加密的 HTTP 请求和响应了。

这样通信的双方也已知三个随机数:Client Random、Server Random 和 Pre Master Secret,就可以生成主密钥了。

参考资料

26 | 信任始于握手:TLS1.2连接过程解析 (geekbang.org

3.4 HTTPS ECDHE 握手解析 | 小林coding (xiaolincoding.com

编程笔记 » 传输安全HTTPS

赞同 (28) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽