04.安全-TLS1.2连接过程

TLS 握手的前几个消息都是明文的,能够在 Wireshark 里直接看。

但只要出现了“Change Cipher Spec”,后面的数据就都是密文了,看到的也就会是乱码,不知道究竟是什么东西。

为了更好地分析 TLS 握手过程,可以再对系统和 Wireshark 做一下设置,让浏览器导出握手过程中的秘密信息,这样 Wireshark 就可以把密文解密,还原出明文。

首先,你需要在 Windows 的设置里新增一个系统变量SSLKEYLOGFILE,设置浏览器日志文件的路径,比如

D:\http_study\log\sslkey.log

然后在 Wireshark 里设置“Protocols-TLS”
(较早版本的 Wireshark 里是“SSL”),在“(Pre)-Master-Secret log filename”里填上刚才的日志文件

ECDHE握手过程


在 TCP 建立连接之后,浏览器会首先发一个“Client Hello”消息,也就是跟服务器“打招呼”。
里面有客户端的版本号、支持的密码套件,还有一个随机数(Client Random),用于后续生成会话密钥

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 512
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 508
            Version: TLS 1.2 (0x0303)
            Random: deb646e741a099b49bfef08f38871a4ac8d86b1f265ea6dc…
            Session ID Length: 32
            Session ID: 559393da63fd63f325d1f52088aa649401260c65f1e499fc…
            Cipher Suites Length: 34
            Cipher Suites (17 suites)
            Compression Methods Length: 1
            Compression Methods (1 method)
            Extensions Length: 401
            Extension: Reserved (GREASE) (len=0)
            Extension: server_name (len=19)
            Extension: extended_master_secret (len=0)
            Extension: renegotiation_info (len=1)
            Extension: supported_groups (len=10)
            Extension: ec_point_formats (len=2)
            Extension: session_ticket (len=0)
            Extension: application_layer_protocol_negotiation (len=14)
            Extension: status_request (len=5)
            Extension: signature_algorithms (len=20)
            Extension: signed_certificate_timestamp (len=0)
            Extension: key_share (len=43)
            Extension: psk_key_exchange_modes (len=2)
            Extension: supported_versions (len=11)
            Extension: compress_certificate (len=3)
            Extension: Reserved (GREASE) (len=1)
            Extension: padding (len=202)

作为“礼尚往来”,服务器收到“Client Hello”后,会返回一个“Server Hello”消息。

把版本号对一下,也给出一个随机数(Server Random),
然后从客户端的列表里选一个作为本次通信使用的密码套件,在这里它选择了“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384”

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 112
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 108
            Version: TLS 1.2 (0x0303)
            Random: 306ba0a553a042f119e52473b67c6e293f3ee61012fff8ff…
            Session ID Length: 32
            Session ID: 27e4112dd0e1299b7fd853c7787c16308bf03435a620a8fd…
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
            Compression Method: null (0)
            Extensions Length: 36
            Extension: renegotiation_info (len=1)
            Extension: server_name (len=0)
            Extension: ec_point_formats (len=4)
            Extension: extended_master_secret (len=0)
            Extension: application_layer_protocol_negotiation (len=11)
    TLSv1.2 Record Layer: Handshake Protocol: Certificate
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 770
        Handshake Protocol: Certificate
            Handshake Type: Certificate (11)
            Length: 766
            Certificates Length: 763
            Certificates (763 bytes)
                Certificate Length: 760
                Certificate: 308202f4308201dca003020102020900fa9c5b27a0c1368d… (id-at-commonName=www.chrono.com)
                    signedCertificate
                    algorithmIdentifier (sha256WithRSAEncryption)
                    Padding: 0
                    encrypted: 6dd90318e47d1b41728f04802a85eedca00a615feed7a67f…
    TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 300
        Handshake Protocol: Server Key Exchange
            Handshake Type: Server Key Exchange (12)
            Length: 296
            EC Diffie-Hellman Server Params
                Curve Type: named_curve (0x03)
                Named Curve: x25519 (0x001d)
                Pubkey Length: 32
                Pubkey: 780f25b44d2ebb5df7ead5e9b6b32c2d40bb7094f16ac7c6…
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Length: 256
                Signature: 6778592c6742cbd45ff120ce72d1a442a8c5cdbb65e792d5…
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 4
        Handshake Protocol: Server Hello Done
            Handshake Type: Server Hello Done (14)
            Length: 0


然后,服务器为了证明自己的身份,就把证书也发给了客户端(Server Certificate)。

接下来是一个关键的操作,因为服务器选择了 ECDHE 算法,所以它会在证书后发送“Server Key Exchange”消息,里面是椭圆曲线的公钥(Server Params),用来实现密钥交换算法,再加上自己的私钥签名认证

TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 300
        Handshake Protocol: Server Key Exchange
            Handshake Type: Server Key Exchange (12)
            Length: 296
            EC Diffie-Hellman Server Params
                Curve Type: named_curve (0x03)
                Named Curve: x25519 (0x001d)
                Pubkey Length: 32
                Pubkey: 780f25b44d2ebb5df7ead5e9b6b32c2d40bb7094f16ac7c6…
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Length: 256
                Signature: 6778592c6742cbd45ff120ce72d1a442a8c5cdbb65e792d5…
  • 1.指明自己使用的椭圆曲线(一般根据客户端的拓展中supported_groups中的选择椭圆曲线算法)

  • 2 服务器本地计算一个大数(BIGNUM),乘上曲线的base point,得到一个新的point,这个point就是公钥,用04+x+y的格式组织起来。04表示unconpressed point,和客户端的ec_point_formats有关。

  • 3 签名 。和RSA握手不同,RSA情况下, 只要能值正常协商密钥,那么必然服务器端有证书对应的私钥,也间接表明了服务器拥有该证书。
    DHE/ECDHE不同,证书对应的私钥并不参与密钥协商,如果要证明服务器拥有证书,则必然有签名的操作(就像双向认证的情况下,客户端需要发送certificate verify)。
    被签名数据从curve type起,至point的y为止。
    对于TLS1.2,签名算法使用client hello拓展中提供的摘要算法;TLS1.0和TLS1.1,如果本地证书是ECC证书,即若要使用ECDSA签名,这种摘要算法为SHA1,其他的情况摘要算法为md5+sha1。

计算摘要之后就调用RSA或者ECDSA进行签名。注意的是,TLS1.2时报文要带上2字节的“Signature Hash Algorithm”,如上图高亮部分,这是TLS1.2协议相较于之前协议不同之处之一,但是这2部分不参与签名计算

这相当于说:“刚才我选的密码套件有点复杂,所以再给你个算法的参数,和刚才的随机数一样有用,别丢了。为了防止别人冒充,我又盖了个章。

”之后是“Server Hello Done”消息,服务器说:“我的信息就是这些,打招呼完毕。”这样第一个消息往返就结束了(两个 TCP 包),结果是客户端和服务器通过明文共享了三个信息:Client Random、Server Random 和 Server Params。

客户端这时也拿到了服务器的证书,那这个证书是不是真实有效的呢?
开始走证书链逐级验证,确认证书的真实性,再用证书公钥验证签名,就确认了服务器的身份:“刚才跟我打招呼的不是骗子,可以接着往下走。”然后,客户端按照密码套件的要求,也生成一个椭圆曲线的公钥(Client Params),用“Client Key Exchange”消息发给服务器。

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

现在客户端和服务器手里都拿到了密钥交换算法的两个参数(Client Params、Server Params),就用 ECDHE 算法一阵算,算出了一个新的东西,叫“Pre-Master”,其实也是一个随机数。

至于具体的计算原理和过程,因为太复杂就不细说了,但算法可以保证即使黑客截获了之前的参数,也是绝对算不出这个随机数的。

现在客户端和服务器手里有了三个随机数:Client Random、Server Random 和 Pre-Master。
用这三个作为原始材料,就可以生成用于加密会话的主密钥,叫“Master Secret”。而黑客因为拿不到“Pre-Master”,所以也就得不到主密钥。为什么非得这么麻烦,非要三个随机数呢?

这就必须说 TLS 的设计者考虑得非常周到了,他们不信任客户端或服务器伪随机数的可靠性,为了保证真正的“完全随机”“不可预测”,把三个不可靠的随机数混合起来,那么“随机”的程度就非常高了,足够让黑客难以猜测。

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

这里的“PRF”就是伪随机数函数,它基于密码套件里的最后一个参数,比如这次的 SHA384,通过摘要算法来再一次强化“Master Secret”的随机性。

主密钥有 48 字节,但它也不是最终用于通信的会话密钥,还会再用 PRF 扩展出更多的密钥,比如客户端发送用的会话密钥(client_write_key)、服务器发送用的会话密钥(server_write_key)等等,避免只用一个密钥带来的安全隐患。

有了主密钥和派生的会话密钥,握手就快结束了。客户端发一个“Change Cipher Spec”,然后再发一个“Finished”消息,把之前所有发送的数据做个摘要,再加密一下,让服务器做个验证。

意思就是告诉服务器:“后面都改用对称算法加密通信了啊,用的就是打招呼时说的 AES,加密对不对还得你测一下。

”服务器也是同样的操作,发“Change Cipher Spec”和“Finished”消息,双方都验证加密解密 OK,握手正式结束,后面就收发被加密的 HTTP 请求和响应了

  • HTTPS 协议会先与服务器执行 TCP 握手,然后执行 TLS 握手,才能建立安全连接
  • 握手的目标是安全地交换对称密钥,需要三个随机数,第三个随机数“Pre-Master”必须加密传输,绝对不能让黑客破解;
  • “Hello”消息交换随机数,“Key Exchange”消息交换“Pre-Master”;
  • “Change Cipher Spec”之前传输的都是明文,之后都是对称密钥加密的密文

TLS协议组成

记录协议

Record Protocol ,规定了TLS收发数据的基本单位。它有点类似TCP里的segment,所有的其它子协议都需要通过记录协议发出
但是多个记录数据可以在1个TCP包里一次性发出,也并不需要像TCP那样返回ACK

警报协议

Alert protocol 职责是向对方发出警报信息,类似http协议里的状态码。
比如protocol_version 就死不支持旧版本 bad_certificate就是证书有问题
收到警报后,另一方可以选择终止连接,也可以选择继续

握手协议

(Handshake Protocol)是 TLS 里最复杂的子协议,要比 TCP 的 SYN/ACK 复杂的多,浏览器和服务器会在握手过程中协商

  • TLS 版本号、
  • 随机数、
  • 密码套件等信息,

然后交换证书和密钥参数,最终双方协商得到会话密钥,用于后续的混合加密系统

变更密码规范协议

(Change Cipher Spec Protocol),它非常简单,就是一个“通知”,告诉对方,后续的数据都将使用加密保护。那么反过来,在它之前,数据都是明文的

第一阶段:C/S两端共享Client Random、Server Random 和 Server Params信息
客户端--->服务器:
客户端的版本号、支持的密码套件,还有一个随机数(Client Random)

服务端--->客户端:
客户端的版本号、选择的客户端列表的密码套件如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384、随机数随机数(Server Random)

服务端--->客户端:
服务端证书(Server Certificate)


服务端--->客户端:
发送Server Key Exchange类型的请求,携带椭圆曲线的公钥(Server Params)用以实现密钥交换算法,另附私钥签名


服务端--->客户端:
发送完毕


第二阶段:证书验证

前验条件:客户端证书链逐级验证、证书公钥验证签名,服务端身份验证成功(证书合法)

客户端--->服务端
发送Client Key Exchange类型的请求,携带椭圆曲线的公钥(Client Params)用以实现秘钥交换算法


第三阶段:主密钥生成

客户端、服务端分别使用Client Params、Server Params通过ECDHE算法计算出随机值pre-master,然后用
Client Random、Server Random 和 Pre-Master三个值作为原材料,用PRF伪随机数函数(利用密码套件的摘要算法再次强化结果
值maser secert的随机性)计算出主密钥Master Secret,

主密钥并不是会话秘钥,还会再用PRF扩展出更多的密钥,比如客户端发送用的会话密钥(client_write_key)、服务器发送用的会话密钥(server_write_key)


客户端--->服务端:
客户端发一个“Change Cipher Spec”,然后再发一个“Finished”消息,把之前所有发送的数据做个摘要,再加密一下,让服务器做个验证.

服务端--->客户端:
服务器也是同样的操作,发“Change Cipher Spec”和“Finished”消息,双方都验证加密解密 OK,握手正式结束.

1.client hello 【client->server】

  • client发送 随机数randomC,tls版本,支持的密码套件,扩展信息到服务端

2.server hello 【server-client】

  • server 发送 随机数randomS,tls版本确认,选择的密码套件,扩展信息到client

3.certificate 【server->client】

4.server key exchange 【server->client】

  • EC Diffie-Hellman Server Params
    • Curve Type(曲线类型)
    • Pubkey
    • Signature Algorithm和Signature

5.server hello done 【server ->client】

https://blog.csdn.net/mrpre/article/details/78025940

posted @ 2020-10-23 22:44  H&K  阅读(1515)  评论(0编辑  收藏  举报