• tls1.3协议实战(二)----Encrypted Extentions


         1、(1)上一篇tls1.3实战(https://www.cnblogs.com/theseventhson/p/14613527.html)分析了client hello和server hello,主要介绍了双方通过tls1.3协议握手的细节,还有一个很大的问题遗留:对于server hello包,wireshark就解析到了0xba这个位置(也就是ChangeCipherSpec),从0xbb到0x58e=1422的位置,还有1234byte并未解析,这些又都是什么数据了?纵观整个协议的握手过程,截至目前看到的都是handshake密钥交换阶段,record传输加密数据的阶段都在哪了? 

      ChangeCipherSpec字段本身是通知对方用协商好的对称密钥加密通信数据,所以从这之后的消息都是进行加密了的,可能是因为Wireshark没有对后续的消息进行解密,所以只是显示了ApplicationData,即加密传输的数据。

           

       这些加密后的数据,那些时record阶段的数据了? record阶段的数据既然加密了,能解密查看么? 如果能,怎么查看了?

       自己随便选个目录,比如我选了这个:D:softwaresslkeylog.log,在环境变量新建一个,取名为SSLKEYLOGFILE,如下:

           

       然后在wireshark的编辑->首选项->Protocols选择TLS(网上有些教程是让选择SSL,但我用的是3.4.0版本,没有SSL选项,只有TLS选项),找到红框框的地方,添上刚才环境变量指定的log文件路径:

           

       配置好后重新用chrome打开网页,sslkeylog.log文件内容:这个是tls1.2的内容,格式为:CLIENT_RANDOM <client_random> <master_secret>,也就是记录了client_random和master_secret;

    CLIENT_RANDOM F6EC7D82E1A3704B9EEC4876FCAAB722E010D7FB4FA8DF332AF48D******** 2576E2B4C11802D86377C80B74504E7E03EDD11EE9CE780F86CB9DF06E30A1EC9FC15C14835252FE036DF7********
    CLIENT_RANDOM 3DC71D07C9C3E512D7FFC5774BBCA8D07097580288BB3C86CA0E4F******** F6C87019AC A076F396E470C435DE478EDAEF9B2D6C72642706321A8A2456FD0A201A39D50EA055F6EA6EE0AEEFB********

       至此,还未dump tls1.3的密钥到sslkeylogfile.log(文件除了几个CLIENT_RANDOM,就没其他内容了),所以wireshark还是无法解密record阶段的内容。网上查了很多资料,期间耗费了好几个小时,终于用这个命令成功把chrome的密钥dump到指定文件:

    "C:Program FilesGoogleChromeApplicationchrome.exe" --ssl-key-log-file=%SSLKEYLOGFILE%

       文件都有61KB大了:

       

      各种密钥收集了近700条:

       

      wireshark也能正常解密了:能看到entrypt extension、certificate、verify、finished

      

         至此:利用chrome dump的key在wireshark中成功解密tls1.3的数据!

      (2)解密注意(这些坑耗费了我好几个小时排查):

    •   环境变量设置好后,电脑不用重启,但浏览器要重启;
    •  在任务管理器看看浏览器进程是不是全部退出,不能有任何残留的实例;如果不确定,建议重启电脑,确保浏览器进程全部退出,没有残留
    •  执行如下的命令:给浏览器认为设置一个参数;(直接打开浏览器是没用的!一定要手动给浏览器设置这个参数!
      "C:Program FilesGoogleChromeApplicationchrome.exe" --ssl-key-log-file=%SSLKEYLOGFILE%

     (3)上面都是现象,原理在这:这里用的是ECDHE算法让双方互相交换公钥,然后各自根据曲线类型和对方的公钥生成对称加密的密钥pre-master-secret。这个对称密钥并未通过网络传输,所以wireshark是抓不到的!怎么才能得到这个密钥了?就是通过上述设置环境变量的方式,让浏览器把pre-master-secret导出到指定的log文件,然后wireshark去指定的文件读密钥,就能解密application data了

       

    2、接下来介绍一下这几个重点的handshake protocol;

    • handshake protocol:certificate;client和server在通信时,为了确认发数据人的身份,就需要认证。这里server会先把证书发给client,client用事先内置的第三方权威认证中心的公钥解密证书,来确认这个证书是不是server发过的(紧接着下一个certificates verify字段就是干这个的)!这两个证书就是google发给client的证书。证书里面有google生成的ECC的公钥,用于和client协商生成对称加密的密钥;既然是证书,包含的内容有很多,两个证书一共有3532byte;

         

         证书中比较重要的字段:

             1) issuer:这个证书的颁发者

        

       2)validity:证书有效期

              

             3)subject:这个证书颁发给谁的,这里明显是google;

               

       4)subjectPublicKeyInfo:server的公钥信息。这里能看出来采用了secp256r1曲线,并提供了server的公钥给client;后续client会根据这个公钥生成对称密钥

               

    • handshake Protocol:certificate verify;这里选用的是secp256r1椭圆曲线来做认证,确保服务器发过来的certificates是没有被篡改的;certificate的hash值是用sha256计算出来的,长71byte;

          

    • handkshake Protocol:Finished;Finished消息是身份验证阶段的最后一条消息,也是第一个使用协商的算法簇进行加密和防篡改保护的消息;Verify Data是通过HMAC计算得来的,包含finished_key和握手消息的hash。 verify_data =HMAC(finished_key,Transcript-Hash(Handshake Context,Certificate, CertificateVerify))

             

     3、 至此,所有的application data都被解密,并还原成了http包:

      

         随便打开一个http包,所有的head信息都能看到:

         

     4、最后做个总结:tls1.3中双方握手通信的流程图如下:

      

    • +表示该报文中值得注意的extension
    • * 表示该内容也可能不被发送
    • {} 表示该内容使用handshake_key加密
    • [] 表示该内容使用application_key加密

       其中:(1)handshake_key是由我们使用的PSK与前两次报文,使用HKDF(内建的某函数,其中会使用到加密套件指定的哈希算法)导出而来的

          (2)application_key则是以整个握手阶段的报文作为输入,计算四次HKDF导出而来

    补充:刚开始学这些通信协议的时候会遇到各种证书,不太能分得清,这里系统性总结一下:

       (1)根证书:由全球权威机构颁发,在浏览器或操作系统出厂时就内置好的(当然证书是可以增加的,如fiddler的证书);chorome查询如下:

              

       根证书核心的功能之一是提供公钥,作为信任链建立的起点!证书内容如下:

             

       (2)中间机构颁发机构:由根证书机构签发的,可直接用户签发网站的证书!这里的证书也是可以添加的,比如fiddler;内容和根证书一样!

             

       (3)个人证书:这里面都是fiddler为了抓包而颁发的,目的是欺骗客户端!

            

       从上面的截图可以看到,为了作为中间人抓包,fiddler在3个地方都安装了证书,这些证书都是怎么工作的了? 为什么安装了证书的fiddler就能解密https这些加密的数据包了?

    •     首先:fiddler要求用户把自己的证书安装在受信任的根证书颁发机构,fiddler证书就成了CA根证书;
    •       其次:再用这个CA根证书给自己颁发中间证书;最后再用这个中间证书伪造各个网站的证书;
    •       最后:一旦拦截客户端的访问请求,就把伪造的这些网站证书发给客户端,让客户端误以为fiddler就是目标网站,达到欺骗的目的!具体做法就是fiddler在伪造的个人证书中内置自己的公钥,后续客户端会利用这个公钥、根据tls1.3协议生成各种premaster key、session key等,fiddler截获后可以直接解密数据了!在客户端看来,以为通信的对方就是网站,其实是fiddler!罪恶之源就是CA根证书被更改,导致整个信任链建立的起点被篡改!

    参考:

    1、https://gohalo.me/post/decrypt-tls-ssl-with-wireshark.html  使用 Wireshark 解密 SSL/TLS 流量

    2、https://strawberrytree.top/blog/2020/09/17/%E4%BD%BF%E7%94%A8openssl%E4%BD%BF%E7%94%A8%E5%A4%96%E9%83%A8psk%E8%BF%9B%E8%A1%8C%E6%8F%A1%E6%89%8B%EF%BC%88tls1-3%EF%BC%89/      使用OpenSSL指定加密套件使用外部PSK进行握手(TLS1.3,OpenSSL3.0)

    3、https://zh.wikipedia.org/wiki/%E6%A0%B9%E8%AF%81%E4%B9%A6  根证书

  • 相关阅读:
    Python疑难杂症:SyntaxError: NonASCII character Python中文处理问题
    程序员健康大全透视身体24小时工作时间表
    ConnectionTimeout,CommandTimeout和executionTimeout的理解
    google map api 与jquery结合使用(3) 图标样式,使用xml和异步请求【转帖】
    新手8周跑步训练计划
    57商城温州地区最大本土网上超市
    7 款仿照 Sinatra 思路的 .NET 框架
    线程池的原理和连接池的原理
    免费网站模版:一个黑色系的公司网站模版(flash幻灯)
    深入浅出REST
  • 原文地址:https://www.cnblogs.com/theseventhson/p/14618157.html
Copyright © 2020-2023  润新知