zoukankan      html  css  js  c++  java
  • 04.安全-TLS1.2连接过程

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

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

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

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

    D:http_studylogsslkey.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

  • 相关阅读:
    网络七层
    微信小程序开发工具 常用快捷键
    BZOJ 1026 windy数 (数位DP)
    BZOJ 1026 windy数 (数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    CodeForces 55D Beautiful numbers (SPOJ JZPEXT 数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3709 Balanced Number (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
    UVA 11361 Investigating Div-Sum Property (数位DP)
  • 原文地址:https://www.cnblogs.com/HKUI/p/13866663.html
Copyright © 2011-2022 走看看