目前已更新系列:
当前:计算机网络--面试总结三(Http与Https)
知识积累之ThreadLocal---InheritableThreadLocal总结
HTTP与HTTPS区别
- 1、HTTP是明文传输的所以存在安全风险,而HTTPS解决了这个问题,他在HTTP与TCP传输层之间引入了TLS/SSL协议,让报文能够加密传输
- 2、HTTP建立只需要进行TCP的握手,HTTPS建立连接需要在进行TCP握手后在进行一个TLS的四次握手
- 3、HTTP默认的端口是80,而HTTPS默认的端口是443
- 4、HTTPS需要向CA机构申请数字证书,来保证服务器的身份是可靠的
HTTP存在的风险HTTPS是怎样解决的
- 1、窃听风险:明文传输,数据泄漏问题
- 2、篡改风险:第三方基于HTTP请求内容进行对内容的篡改
- 3、冒充风险:第三方可以冒充访问的服务端,比如你访问百度,这个百度可能是第三方冒充的
针对与这些问题HTTPS解决方法如下:
- 针对于窃听风险,是通过信息加密来解决的
- 针对于篡改风险,是通过校验机制来解决的
- 针对于冒充风险,是通过身份证书来解决的
HTTPS的握手过程
非对称加密算法ECDHE算法
离散对数原理
离散对数原理:离散对数其实就是在对数计算的基础上增加一个取模运算,这样就可以使得正向计算如下,比较容易,正向计算出来的值就可以当作公钥,但是逆向计算却不容易就是因为增加了一个取模运算
对于普通的对数运算
离散对数:就是对正向运算通过取模后才得到对数b,这样的好处是正向运算可以很容易算出b,但是知道b,p,a却很难推出i
DH算法
DH算法其实就是采用离散对数的方式,分别进行公钥的生成,过程如下
- 对于客户端:定义一个离散对数中的底数g,和模数p,然后生成一个随机数,之后通过离散对数生成一个公钥A,然后将离散对数公用的底数g,模数p,以及生成的公钥A发送给服务端
- 对于服务端:得到生成离散对数的条件底数g,模数p,后同样随机生成一个随机数作为私钥b,然后通过离散对数计算得到公钥B后,将公钥B传给客户端
- 此时客服端具有自己的私钥a,服务端公要B,以及离散对数参数g,p然后就可以通过这个进行计算出回话密钥
-
- K=B^a mod p=(g^b mod p)^a=g^(ab) mod p
- 同样服务端也具备私钥b,客户端公要A,以及离散对数参数g,p,可以计算会话密钥
-
- K=A^b mod p=(g^a mod p)^b=g^(ab) mod p
- 综上,客服端,服务端就计算出相同的会话密钥了
可以从上面过程看到:整个密钥协商过程,客服端服务端之间通信都只传输了公开的信息g,p,A,B,这些加上利用各自的私钥是离散对数正向生成的过程,生成会话密钥后,其他人拿到K也就不容易逆向求出私钥了(看离散对数内容)
DHE
DH会话密钥的生成方式主要有两种
- static DH,已经废弃,
-
- 主要思想就是利用上面说的DH算法,然后固定服务端的私钥,而每次建立连接时客户端的私钥随机生成
- 缺点就是:不具备向前安全性,因为随着时间推移,由于服务端私钥是固定的,黑客可以从海量数据中尝试破解
- DHE算法,(多的E表示临时的意思),现在常用
-
- 针对于上面问题,将客户端、服务端一起每次密钥交换通信是,都随机生成、临时的私钥这样就解决了向前安全性问题
- DHE算法虽然解决了向前安全性问题,但是由于计算、交互比较复杂,是的性能较差,所以有了后面的ECDHE算法
ECDHE
ECDHE 算法是在 DHE 算法的基础上利用了 ECC 椭圆曲线特性,可以用更少的计算量计算出公钥,以及最终的会话密钥。
ECDHE 密钥交换的基本步骤
- 选择椭圆曲线和基点:
-
- 双方事先同意使用特定的椭圆曲线和曲线上的一个基点 G。这些参数是公开的,并且通常是通过标准或协议来定义的。
- 生成私钥和公钥:
-
- 小红和小明各自随机生成一个私钥(d1 和 d2),这些私钥是保密的。
- 他们将各自的私钥与公共基点 G 相乘,得到各自的公钥(A=d1G 和 B=d2G)。公钥是可以公开共享的。
- 交换公钥:
-
- 小红和小明通过某种安全的方式(如 TLS 握手过程)交换彼此的公钥。
- 计算共享密钥:
-
- 小红使用自己的私钥 d1 和小明的公钥 B 来计算 d1B=d1(d2G)=d1d2G。
- 同时,小明使用自己的私钥 d2 和小红的公钥 A 来计算 d2A=d2(d1G)=d2d1G。
- 由于椭圆曲线上的乘法满足交换律和结合律,因此 d1d2G=d2d1G,双方计算出的结果是相同的点 (x,y),这个点的 x 坐标(有时是整个点 (x,y))被用作共享密钥。
安全性
- 离散对数难题:在椭圆曲线上,从公钥(如 A=d1G)推导出私钥 d1 是非常困难的,这被称为椭圆曲线上的离散对数问题。这是 ECDHE 安全性的基础。
- 临时私钥:由于私钥是随机且临时生成的(即“ephemeral”),每次会话都使用不同的私钥,这增加了安全性,因为即使一个私钥在某个会话中被泄露,它也不会影响其他会话的安全性。
- 前向保密:由于私钥是临时的,并且仅在单个会话中使用,因此即使长期密钥(如服务器的私钥)在将来被泄露,过去的会话密钥也不会受到影响,这提供了前向保密性。
总结
ECDHE 密钥交换算法通过利用椭圆曲线上的数学性质,提供了一种安全、高效的方式来生成共享密钥。这种算法在 TLS/SSL 等协议中广泛使用,为网络通信提供了强大的加密基础。
这个过程中,双方的私钥都是随机、临时生成的,都是不公开的,即使根据公开的信息(椭圆曲线、公钥、基点 G)也是很难计算出椭圆曲线上的离散对数(私钥)
HTTPS中ECDHE的握手流程
第一次握手Client Hello:
- 客户端生成一个随机数、发送自己支持的加密套件,TLS版本号等
第二次握手 Server Hello:
- 服务端接收到客服端发送的内容后,会在本地生成一个随机数以及选择合适的TLS版本
- 会选择合适的加密套件然后发送给客户端,而这个加密套件就包含了密钥协商算法比如ECDHE,签名算法算则RSA,以及握手后试用的对称加密算法比如AES等
- 接着服务端会继续发送Certificate消息表明自己的身份,即把身份证书发送过去
- 最后需要发送Server Key Exchange消息(因为选择了ECDHE算法),作用如下
-
- 1、选择合适的椭圆曲线,然后确定好椭圆基点G
- 2、再次生成一个随机数作为服务端椭圆曲线的私钥,保留在本地
- 3、根据基点G和私钥计算出服务端的椭圆曲线公钥
- 最后为了保证这个椭圆公钥不被第三方篡改,服务端会使用RSA签名算法给服务端的椭圆曲线公钥做签名,然后发送给客户端
- 最后发送一个Server Hello Done表示第二次握手结束
- 相当于在第二次握手时完成了选择合适的加密算法、TLS版本、生成随机数返回,然后选择合适的椭圆曲线、再次生成一个随机数作为服务端私钥,然后通过ECDHE算法进行加密得到公钥,最后将公钥进行RSA加密后发送返回
第三次握手:
- 客服端接收到服务端信息之后,首先就先去校验证书是否合法,如果身份合法
- 那么客户端会在本地生成一个随机数作为客户端私钥,然后结合服务端选择的椭圆曲线,基点等生成客户端的椭圆曲线公钥,然后将该客户端公钥发送给服务端
到这里客户端、服务端就分别拥有了对方的椭圆曲线公钥、自己的私钥、以及椭圆曲线、基点G了,即双方都可以通过这些信息通过椭圆曲线计算出椭圆曲线中对应的点(x,y)了,其中x的坐标双方都是一样的,但是x还不是最终的会话密钥。最终的会话密钥=客户端第一次握手的随机数+服务端的随机数(ECHDHE算法生成的共享密钥x)来生成
之所以这样做是为了再次提高会话密钥的安全性,即将三个随机的数组合在一起安全性肯定更高
算好会话密钥之后,客户端会发送一个Change Cipher Spec的消息,告诉服务端后续该用对称加密算法进行通信就行了
到这离第三次握手就结束了
TLS第四次握手
最后服务端也会有一个相同的操作,发送一个Change Cipher Spec和 Encrypted Handshake Massage消息,如果双方验证加密解密都没问题,那么握手正式完成,既可以正常的进行机密Http请求和响应了
小结
RSA和ECDHE握手的区别
- RSA密钥协商算法不支持向前保密,ECDHE支持向前保密
- RSA密钥协商算法之后在第四次TLS握手结束后,才能进行应用的数据传输,而对于ECDHE来说,客户端可以在第三次握手结束后,就可以提前发送加密的HTTP数据,节省了一个往返时间(这是RFC规定的,具体原因不知道,因为按理来说,RSA其实第三次握手结束,两边也应该有了相同会话密钥才对)
- 试用ECDHE,在TLS的第二次握手中,会发送Server Key Exchange的消息发送椭圆曲线的信息,而RSA不会
- RSA性能相对于ECDHE来说较慢
对RSA握手来说
其实RSA这个对称加密算法主要就是在第三次次握手使用客户端生成的随机数用RSA进行利用公钥+第三个随机数加密,然后在服务端使用RSA通过私钥来进行解密得到服务端的随机数
ClientHello
首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。
在这一步,客户端主要向服务器发送以下信息:
(1)客户端支持的 TLS 协议版本,如 TLS 1.2 版本。
(2)客户端生产的第一个随机数(Client Random),后面用于生成「会话秘钥」条件之一。
(3)客户端支持的密码套件列表,如 RSA 加密算法。
- SeverHello
服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:
(1)确认 TLS 协议版本,如果浏览器不支持,则关闭加密通信,并保存客服端发来的第一个随机数。
(2)服务器生产的第二个随机数(Server Random),也是后面用于生产「会话秘钥」条件之一。
(3)从客服端发过来客服端所支持的加密套件中选择确认的密码套件列表,如 RSA 加密算法。
(4)将服务器的数字证书发送给客服端。
3.客户端回应
客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。
如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,客服端产生第三个随机数,也叫预主密钥,然后使用公钥对与主密钥进行加密后发送给服务端
(1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。
(2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
上面第一项的随机数是整个握手阶段的第三个随机数,会发给服务端,所以这个随机数客户端和服务端都是一样的。
服务器和客户端有了这三个随机数(Client Random、Server Random、pre-master key),接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。
- 服务器的最后回应
如果双方都验证加密和解密没问题,那么握手正式完成。
(1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
至此,整个 TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。
参看博客
这里主要是对小林coding上的知识进行总结和结合自己理解进行总结的,大家如果需要详细了解相关知识可以到对应链接进行学习:3.4 HTTPS ECDHE 握手解析 | 小林coding