本文转载自微信公众号“小林编码”,作者小林编码。转载本文请联系小林编码公众号。HTTPS常用的密钥交换算法有两种,即RSA和ECDHE算法。其中,RSA是一种比较传统的密钥交换算法,不具备前向安全性,所以现在很少被服务器使用。ECDHE算法具有前向安全性,因此得到广泛应用。上一篇文章介绍了RSA握手过程,今天这篇文章将“从理论到实际抓包”介绍一下ECDHE算法。离散对数ECDHE密钥协商算法是DH算法的演化,所以我们先从DH算法说起。DH算法是一种非对称加密算法,因此可以用来进行密钥交换,算法的核心数学思想是离散对数。当你听到这个数学概念时,你是否感到灰心?别怕,这次我不说离散对数求导的过程,简单说一下它的数学公式。离散对数是“离散+对数”两个数学概念的结合,所以我们先复习一下对数。说到对数,就必须说到指数,因为它们是互为反函数,指数是幂运算,对数是指数的逆运算。例如,如果底数为2,则指数和对数计算公式如下图所示:那么当底数为2时,32的对数为5,64的对数为6。计算过程如下:算术运算的值可以是连续的,而离散对数的值不能是连续的,所以又叫“离散”。取余,编程语言对应的运算符是“%”,也可以用mod表示。离散对数的概念如下图所示:上图中,底数a和模数p是离散对数的公共参数,即public,b是实数,i是对数。知道对数,就可以用上面的公式来计算实数。但反过来,知道实数就很难推导出对数。尤其是当模数p是一个非常大的质数时,即使知道底数a和实数b,以现有计算机的计算水平几乎不可能计算出离散对数,这是计算离散对数的数学基础DH算法。DH算法识别的是离散对数,我们来看看DH算法是如何交换密钥的。现在假设小红和小明同意使用DH算法交换密钥,那么根据离散对数,小红和小明需要确定模和底作为算法的参数,这两个参数是公开的,用P和G替代名称。然后小红和小明各自生成一个随机整数作为私钥。双方的私钥必须严格保管,不能泄露。小红的私钥叫做a,小明的私钥叫做b。现在小红和小明都有P和G以及各自的私钥,所以可以计算出公钥:小红的公钥记为A,A=G^a(modP);小明的公钥记为AsB,B=G^b(modP);A和B也是公开的,因为根据离散对数原理,从实数(A和B)中反算出对数a和b是非常困难的,至少现有计算机的计算能力是无法破解的。如果量子计算机出来,可能会被破解。当然,如果真的有量子计算机问世,那么密钥协商算法就得进行大幅度的升级。双方交换各自的DH公钥后,小红一共有5个号码:P、G、a、A、B,小明手里也有5个号码:P、G、b、B、A。那么小红进行运算:B^a(modP),结果为K。由于离散对数的幂运算有交换律,小明进行运算:A^b(modP),结果也为K,这个K就是小红和小明之间使用的对称加密密钥,可以作为会话密钥。可以看出,在整个密钥协商过程中,小红和小明公开了4条信息:P、G、A、B,其中P、G为算法的参数,A、B为公钥,a,b是黑客无法获得双方保存的私钥。因此,黑客只能从公开的P、G、A、B入手计算离散对数(私钥)。之前多次强调,根据离散对数原理,如果P是一个很大的数,以现有计算机的计算能力是很难破解私钥a和b的。如果不能破解私钥,就不可能计算出会话密钥,所以DH密钥交换是安全的。DHE算法根据私钥的生成方式分为两种实现:静态DH算法,已被废弃;现在常用的DHE算法;静态DH算法中一方的私钥是静态的,也就是说,每次协商密钥时,一方的私钥都是一样的。一般服务器端是固定的,即a不变,客户端的私钥是随机生成的。因此,DH交换密钥时,只有客户端的公钥发生变化,而服务器的公钥保持不变。随着时间的推移,黑客会在密钥协商过程中截获大量数据,因为密钥协商过程中的一些数据是公开的,黑客可以利用这些数据暴力破解服务器的私钥,然后计算sessionkey,所以之前截获的加密数据会被破解,所以静态DH算法不具有前向安全性。由于一方的私钥是固定的,存在被破解的风险,所以干脆让双方的私钥随机生成,在每次密钥交换通信时暂存。这种方法就是DHE算法,E的全称是ephemeral(临时)。因此,即使强大的黑客破解了某个通信进程的私钥,其他通信进程的私钥仍然是安全的,因为各个通信进程的私钥之间没有任何关系,是独立的。这确保了“前向安全”。ECDHE算法DHE算法计算性能较差,需要做大量的乘法运算。为了提高DHE算法的性能,现在出现了一种应用广泛的密钥交换算法——ECDHE算法。ECDHE算法在DHE算法的基础上利用了ECC椭圆曲线的特性,可以用较少的计算量计算出公钥和最终会话密钥。小红和小明使用ECDHE密钥交换算法的过程:双方事先确定好使用哪条椭圆曲线以及曲线上的基点G。这两个参数是公开的;双方随机生成一个随机数作为私钥d,与基点G相乘得到公钥Q(Q=dG),此时小红的公私钥分别为Q1和d1,小明的公钥和私钥键是Q2和d2;双方交换公钥,最后小红计算出点(x1,y1)=d1Q2,小明计算出点(x2,y2)=d2Q1,因为在椭圆曲线上可以满足乘法交换结合律,所以d1Q2=d1d2G=d2d1G=d2Q1,所以两边的x坐标是一样的,所以就是共享秘密,会话密钥。在这个过程中,双方的私钥是随机临时生成的,不对外公开。即使基于公开信息(椭圆曲线、公钥、基点G),也很难计算出椭圆曲线(私钥)上的离散对数。ECDHE握手流程了解了ECDHE算法的基本原理后,下面我们结合实际情况来看一下。我使用Wireshark工具捕获了使用ECDHE密钥协商算法的TSL握手过程。可以看到是四次握手:细心的朋友应该发现了,使用ECDHE,客户端在第四次TLS握手之前就已经发送了。对于RSA握手过程,必须先完成TLS四次握手,才能传输应用数据。因此,与RSA握手过程相比,ECDHE节省了一个消息往返时间。在连接完全建立之前发送应用数据,提高了传输效率。接下来分析ECDHE的每次握手过程。第一次TLS握手客户端首先会发送一条“ClientHello”消息,其中包含客户端使用的TLS版本号、支持的密码套件列表以及生成的随机数(ClientRandom)。在第二次TLS握手中,服务器收到客户端的“问候语”,同样返回问候语,并返回一条“ServerHello”消息,其中包含了服务器确认的TLS版本号,同时还给出了一个随机数(服务器随机)。然后从客户端的密码套件列表中选择合适的密码套件。但是,这次选择的密码套件与RSA不同。这次我们来分析一下密码组的含义。"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"密钥协商算法使用ECDHE;签名算法使用RSA;握手后的通信采用AES对称算法,密钥长度为256位,分组方式为GCM;摘要算法使用SHA384;发送“证书”消息也会将证书发送给客户端。这一步与RSA握手过程有很大不同,因为服务器选择的是ECDHE密钥协商算法,所以在发送证书后会发送“ServerKeyExchange”消息。在这个过程中,服务端做了三件事:选中名为named_curve的椭圆曲线,选中椭圆曲线,相当于椭圆曲线的基点G,并设置,这一切都会公开给客户端;生成随机数作为服务端私有椭圆曲线密钥保存在本地;根据基点G和私钥计算服务端的椭圆曲线公钥,并公开给客户端。为了保证椭圆曲线公钥不被第三方篡改,服务端会使用RSA签名算法对服务端的椭圆曲线公钥进行签名。接着是“ServerHelloDone”消息,服务器和客户端说:“这些是我提供的信息,问候结束。”至此,完成了TLS的双向握手。目前客户端和服务端以明文形式共享如下信息:ClientRandom,ServerRandom,使用的椭圆曲线,椭圆曲线的基点G,服务端椭圆曲线的公钥。这些信息非常重要,是后续生成会话密钥的素材。第三次TLS握手中收到服务器发来的证书后,客户端自然要验证证书是否合法。如果证书是合法的,那么来自服务器的身份就没有问题。在验证证书的过程中,会逐级验证证书链,确认证书的真实性,然后使用证书的公钥来验证签名,从而可以确定服务器的身份。确认的。确认无误后,就可以继续往下了。客户端会生成一个随机数作为客户端椭圆曲线的私钥,然后根据服务器给的信息生成客户端的椭圆曲线公钥,然后用“ClientKeyExchange”消息发送给服务器.至此,双方都有对方的椭圆曲线公钥,自己的椭圆曲线私钥,以及椭圆曲线基点G。因此,双方计算点(x,y),其中x坐标值相同对于双方。在讲ECDHE算法的时候,说x是会话密钥,但是在实际应用中,x并不是最终的会话密钥。.还记得在TLS握手阶段,客户端和服务端都会生成一个随机数并传递给对方吗?最终的会话密钥是由三种材料生成的“客户端随机数+服务器随机数+x(ECDHE算法))”计算得到的共享密钥。之所以这么麻烦,是因为TLS设计者不相信其可靠性客户端或服务端的“伪随机数”,很高,足以让黑客计算出最终的会话密钥,更安全。服务器使用对称算法对通信进行加密,然后客户端发送“加密握手消息”消息,对之前发送的数据进行汇总,然后用对称密钥加密,让服务器进行验证验证本次生成的对称密钥是否可以正常使用。在第四次TLS握手结束时,服务器将执行相同的操作,发送“ChangeCipherSpec”和“EncryptedHandshakeMessage”消息。如果双方验证加解密都OK,则握手正式完成。这样加密后的HTTP请求和响应就可以正常收发了。总结RSA和ECDHE握手过程的区别:RSA密钥协商算法“不支持”前向保密,ECDHE密钥协商算法“支持”前向保密;使用RSA密钥协商算法,TLS可以在应用数据传输之前完成四次握手,而对于ECDHE算法,客户端可以提前发送加密的HTTP数据,无需等待服务器的最后一次TLS握手,节省往返时间一条消息;使用ECDHE,在第二次TLS握手时,会有服务器发送的“ServerKeyExchange”消息,但在RSA握手过程中没有这个消息;巨肩https://zh.wikipedia.org/wiki/EllipticCurveDiffie-HellmanKeyExchangehttps://en.wikipedia.org/wiki/EllipticCurveshttps://en.wikipedia.org/wiki/Diffie-HellmanKey交流https://time.geekbang.org/column/article/148188https://zhuanlan.zhihu.com/p/106967180原文链接:https://mp.weixin.qq.com/s/pLyR8zuw4l7Z6sdUZ4IL5w
