首页 > 编程语言 >网络2️⃣HTTPS-密钥交换算法

网络2️⃣HTTPS-密钥交换算法

时间:2023-07-08 16:33:19浏览次数:44  
标签:TLS 私钥 算法 密钥 HTTPS 服务端 客户端

SSL/TLS

HTTPS 是在 TCPHTTP 之间添加 SSL/TLS 安全协议

解决 HTTP 的安全性问题。

  • 在 HTTP 中,通信之前需要进行 TLS 握手。
  • 密钥交换算法:不同密钥交换算法的 TLS 握手流程不同。
    • RSA:简单,但存在前向安全问题(如果服务端私钥泄漏,过去被第三方截获的所有 TLS 通讯密文都会被破解)
    • ECDHE:复杂,但安全(大部分网站使用)

RSA 握手

四次握手

  • Wireshark 抓包

  • 示意图

第一次握手

Client Hello

Client Hello:客户端向服务器发起加密通信请求

  1. 客户端随机数(用于生成会话密钥)

  2. 客户端支持的 TLS 版本(e.g. TLS/1.2)

  3. 客户端支持的密码套件列表(e.g. RSA)

第二次握手

Sever Hello

Sever Hello:服务器收到客户端请求后,发出响应。

  1. 服务器随机数(用于生成会话密钥)

  2. 服务端确认 TLS 版本

  3. 服务端确认密码套件列表

密码套件格式

TLS_密钥交换算法_签名算法_WITH_对称加密算法_摘要算法

示例:TLS_RSA_WITH_AES_128_GCM_SHA256

  • TLS
  • RSA:本来 WITH 前有 2 个单词,此处代表密钥交换算法和签名算法都是 RSA。
  • WITH
  • AES_128_GCM:握手后通信采用 AES 作为对称加密算法,密钥长度 128 位,分组模式是 GCM。
  • SHA256:摘要算法,用于消息认证和产生随机数;

Server Certificate

Server Certificate:服务器的数字证书。

Server Hello Done

Server Hello Done:代表 Server 第一次响应结束。

客户端验证证书

客户端拿到了服务端的数字证书后,需要校验数字证书的真实性。

数字证书和 CA

数字证书:用于认证公钥持有者的身份,防止第三方冒充。

i.e. 告诉客户端,该服务端身份是否可信。

  • 公钥
  • 持有者信息
  • 证书认证机构(CA)的信息
  • CA 对这份文件的数字签名及使用的算法
  • 证书有效期
  • 还有一些其他额外信息

数字证书认证机构Certificate Authority)

  • 网络中具有极高可信度的公证中心。
  • CA 拥有一对公钥和私钥。
    • CA 私钥保密,用于对服务器公钥加密生成数字签名。
    • CA 公钥已预先内置到浏览器或操作系统中,用于验证签名真实性。

数字证书签发和验证

CA 签发证书

  • 服务器公钥、用途、颁发者、有效时间等信息打包,进行哈希计算得到一个 Hash 值。
  • 使用 CA 私钥对 Hash 值加密,生成 CA 数字签名
  • CA 数字签名 添加在文件证书上,形成数字证书。

客户端

  1. 使用相同的哈希算法,计算服务器数字证书信息的 Hash 值(H1)。

  2. 使用 CA 公钥对服务器数字证书中的数字签名解密(得到 H2)。

  3. 对比 H1 和 H2,相同说明证书是由 CA 真实提供的,否则说明是伪造的。

  4. 数字证书中获取服务器公钥,使用它对报文进行加密发送。

第三次握手

客户端验证证书可信后,准备第三次握手。

Client Key Exchange

Client Key Exchange:发送预主密钥(pre-master

  1. 生成随机数(预主密钥,用于生成会话密钥)。

  2. 使用服务器公钥加密后发出。

生成会话密钥Master Secret):

用于后续 HTTP 通信的对称加密。

  • 客户端:根据双方协商的算法,结合三个随机数生成本次通信的会话密钥
  • 服务器:收到客户端发送的预主密钥后(使用服务器私钥解密),同理得到一个相同的会话密钥

Change Cipher Spec

Change Cipher Spec:通知服务器,之后使用会话密钥进行加密通信。

Finished

Finished(Encrypted Handshake Message):客户端握手结束

  • 将之前所有内容发生的数据生成一个摘要,使用会话密钥加密后发出。

  • 用于服务端校验,验证加密通信是否可用、握手信息是否有被中途篡改过。

第四次握手

Change Cipher Spec

Change Cipher Spec:之后使用会话密钥进行加密通信。

Finished

Finished(Encrypted Handshake Message):服务端握手结束

  • 将之前所有内容发生的数据生成一个摘要,使用会话密钥加密后发出。
  • 用于客户端校验

客户端校验通过后,握手正式完成。

之后采用会话密钥进行对称加密通信。

RSA 缺陷 - 前向保密

RSA 不支持前向保密

  • 客户端传递的预主密钥(pre-master)是用服务器公钥加密的。
  • 如果服务器私钥泄漏,过去被第三方截获的 TLS 通信密文都会被破解。

ECDHE 握手

离散对数

ECDHE 密钥协商算法是 DH 算法演进过来的,所以我们先从 DH 算法说起。

DH 算法是非对称加密算法, 因此它可以用于密钥交换,该算法的核心数学思想是离散对数

是不是听到这个数学概念就怂了?不怕,这次不会说离散对数推导的过程,只简单提一下它的数学公式。

离散对数是「离散 + 对数」的两个数学概念的组合,所以我们先来复习一遍对数。

要说起对数,必然要说指数,因为它们是互为反函数,指数就是幂运算,对数是指数的逆运算。

举个栗子,如果以 2 作为底数,那么指数和对数运算公式,如下图所示:

那么对于底数为 2 的时候, 32 的对数是 5,64 的对数是 6,计算过程如下:

对数运算的取值是可以连续的,而离散对数的取值是不能连续的,因此也以「离散」得名,

离散对数是在对数运算的基础上加了「模运算」,也就说取余数,对应编程语言的操作符是「%」,也可以用 mod 表示。离散对数的概念如下图:

上图的,底数 a 和模数 p 是离散对数的公共参数,也就说是公开的,b 是真数,i 是对数。知道了对数,就可以用上面的公式计算出真数。但反过来,知道真数却很难推算出对数。

特别是当模数 p 是一个很大的质数,即使知道底数 a 和真数 b ,在现有的计算机的计算水平是几乎无法算出离散对数的,这就是 DH 算法的数学基础。


DH 算法

认识了离散对数,我们来看看 DH 算法是如何密钥交换的。

现假设小红和小明约定使用 DH 算法来交换密钥,那么基于离散对数,小红和小明需要先确定模数和底数作为算法的参数,这两个参数是公开的,用 P 和 G 来代称。

然后小红和小明各自生成一个随机整数作为私钥,双方的私钥要各自严格保管,不能泄漏,小红的私钥用 a 代称,小明的私钥用 b 代称。

现在小红和小明双方都有了 P 和 G 以及各自的私钥,于是就可以计算出公钥

  • 小红的公钥记作 A,A = G ^ a ( mod P );
  • 小明的公钥记作 B,B = G ^ b ( mod P );

A 和 B 也是公开的,因为根据离散对数的原理,从真数(A 和 B)反向计算对数 a 和 b 是非常困难的,至少在现有计算机的计算能力是无法破解的,如果量子计算机出来了,那就有可能被破解,当然如果量子计算机真的出来了,那么密钥协商算法就要做大的升级了。

双方交换各自 DH 公钥后,小红手上共有 5 个数:P、G、a、A、B,小明手上也同样共有 5 个数:P、G、b、B、A。

然后小红执行运算:B ^ a ( mod P ),其结果为 K,因为离散对数的幂运算有交换律,所以小明执行运算:A ^ b ( mod P ),得到的结果也是 K。

这个 K 就是小红和小明之间用的对称加密密钥,可以作为会话密钥使用。

可以看到,整个密钥协商过程中,小红和小明公开了 4 个信息:P、G、A、B,其中 P、G 是算法的参数,A 和 B 是公钥,而 a、b 是双方各自保管的私钥,黑客无法获取这 2 个私钥,因此黑客只能从公开的 P、G、A、B 入手,计算出离散对数(私钥)。

前面也多次强调, 根据离散对数的原理,如果 P 是一个大数,在现有的计算机的计算能力是很难破解出 私钥 a、b 的,破解不出私钥,也就无法计算出会话密钥,因此 DH 密钥交换是安全的。


DHE 算法

根据私钥生成的方式,DH 算法分为两种实现:

  • static DH 算法,这个是已经被废弃了;
  • DHE 算法,现在常用的;

static DH 算法里有一方的私钥是静态的,也就说每次密钥协商的时候有一方的私钥都是一样的,一般是服务器方固定,即 a 不变,客户端的私钥则是随机生成的。

于是,DH 交换密钥时就只有客户端的公钥是变化,而服务端公钥是不变的,那么随着时间延长,黑客就会截获海量的密钥协商过程的数据,因为密钥协商的过程有些数据是公开的,黑客就可以依据这些数据暴力破解出服务器的私钥,然后就可以计算出会话密钥了,于是之前截获的加密数据会被破解,所以 static 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 第四次握手前,客户端就已经发送了加密的 HTTP 数据,而对于 RSA 握手过程,必须要完成 TLS 四次握手,才能传输应用数据。

所以,ECDHE 相比 RSA 握手过程省去了一个消息往返的时间,这个有点「抢跑」的意思,它被称为是「TLS False Start」,跟「TCP Fast Open」有点像,都是在还没连接完全建立前,就发送了应用数据,这样便提高了传输的效率。

接下来,分析每一个 ECDHE 握手过程。

TLS 第一次握手

客户端首先会发一个「Client Hello」消息,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,以及生成的随机数(Client Random

TLS 第二次握手

服务端收到客户端的「打招呼」,同样也要回礼,会返回「Server Hello」消息,消息面有服务器确认的 TLS 版本号,也给出了一个随机数(Server Random,然后从客户端的密码套件列表选择了一个合适的密码套件。

不过,这次选择的密码套件就和 RSA 不一样了,我们来分析一下这次的密码套件的意思。

「 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384」

  • 密钥协商算法使用 ECDHE;
  • 签名算法使用 RSA;
  • 握手后的通信使用 AES 对称算法,密钥长度 256 位,分组模式是 GCM;
  • 摘要算法使用 SHA384;

接着,服务端为了证明自己的身份,发送「Certificate」消息,会把证书也发给客户端。

这一步就和 RSA 握手过程有很大到区别了,因为服务端选择了 ECDHE 密钥协商算法,所以会在发送完证书后,发送「Server Key Exchange」消息。

这个过程服务器做了三件事:

  • 选择了名为 x25519 的椭圆曲线,选好了椭圆曲线相当于椭圆曲线基点 G 也定好了,这些都会公开给客户端;
  • 生成随机数作为服务端椭圆曲线的私钥,保留到本地;
  • 根据基点 G 和私钥计算出服务端的椭圆曲线公钥,这个会公开给客户端。

为了保证这个椭圆曲线的公钥不被第三方篡改,服务端会用 RSA 签名算法给服务端的椭圆曲线公钥做个签名。

随后,就是「Server Hello Done」消息,服务端跟客户端表明:“这些就是我提供的信息,打招呼完毕”。

至此,TLS 两次握手就已经完成了,目前客户端和服务端通过明文共享了这几个信息:Client Random、Server Random 、使用的椭圆曲线、椭圆曲线基点 G、服务端椭圆曲线的公钥,这几个信息很重要,是后续生成会话密钥的材料。

TLS 第三次握手

客户端收到了服务端的证书后,自然要校验证书是否合法,如果证书合法,那么服务端到身份就是没问题的。校验证书的过程会走证书链逐级验证,确认证书的真实性,再用证书的公钥验证签名,这样就能确认服务端的身份了,确认无误后,就可以继续往下走。

客户端会生成一个随机数作为客户端椭圆曲线的私钥,然后再根据服务端前面给的信息,生成客户端的椭圆曲线公钥,然后用「Client Key Exchange」消息发给服务端。

至此,双方都有对方的椭圆曲线公钥、自己的椭圆曲线私钥、椭圆曲线基点 G。于是,双方都就计算出点(x,y),其中 x 坐标值双方都是一样的,前面说 ECDHE 算法时候,说 x 是会话密钥,但实际应用中,x 还不是最终的会话密钥

还记得 TLS 握手阶段,客户端和服务端都会生成了一个随机数传递给对方吗?

最终的会话密钥,就是用「客户端随机数 + 服务端随机数 + x(ECDHE 算法算出的共享密钥) 」三个材料生成的

之所以这么麻烦,是因为 TLS 设计者不信任客户端或服务器「伪随机数」的可靠性,为了保证真正的完全随机,把三个不可靠的随机数混合起来,那么「随机」的程度就非常高了,足够让黑客计算不出最终的会话密钥,安全性更高。

算好会话密钥后,客户端会发一个「Change Cipher Spec」消息,告诉服务端后续改用对称算法加密通信。

接着,客户端会发「Encrypted Handshake Message」消息,把之前发送的数据做一个摘要,再用对称密钥加密一下,让服务端做个验证,验证下本次生成的对称密钥是否可以正常使用。

TLS 第四次握手

最后,服务端也会有一个同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。于是,就可以正常收发加密的 HTTP 请求和响应了。


总结

RSA 和 ECDHE 握手过程的区别:

  • RSA 密钥协商算法「不支持」前向保密,ECDHE 密钥协商算法「支持」前向保密;
  • 使用了 RSA 密钥协商算法,TLS 完成四次握手后,才能进行应用数据传输,而对于 ECDHE 算法,客户端可以不用等服务端的最后一次 TLS 握手,就可以提前发出加密的 HTTP 数据,节省了一个消息的往返时间(这个是 RFC 文档规定的,具体原因文档没有说明,所以这点我也不太明白);
  • 使用 ECDHE, 在 TLS 第 2 次握手中,会出现服务器端发出的「Server Key Exchange」消息,而 RSA 握手过程没有该消息;

标签:TLS,私钥,算法,密钥,HTTPS,服务端,客户端
From: https://www.cnblogs.com/secretmrj/p/17537442.html

相关文章

  • 【算法】根据二叉树的级别返回排序后的元素列表
    根据给定的Node树节点,返回包含按级别排序的树中元素的列表,这意味着根元素位于第一位,然后根子元素(从左到右)位于第二位和第三位,依此类推。1publicclassNode2{3publicNodeLeft;4publicNodeRight;5publicintValue;67publicNode(No......
  • 手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实
    手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实体识别、CypherCheetsheet详细教学等效果预览:1.知识图谱存储方式知识图谱存储方式主要包含资源描述框架(ResourceDescriptionFramework,RDF)和图数据库(GraphDatabase)。1.1资源描述框......
  • 一文彻底搞懂MySQL基础:B树和B+树的区别 转载 https://blog.csdn.net/a519640026/arti
    写在前面大家在面试的时候,肯定都会被问到MySql的知识,以下是面试场景:面试官:对于MySQL,你对他索引原理了解吗?我:了解面试官:MySQL的索引是用什么数据机构的?我:B+树面试官:为什么要用B+树,而不是B树?我:…面试官:用B+树作为MySql的索引结构,用什么好处?我:…B树和B+树是MySQL索引使用的数据结构......
  • http 和 https区别,自动携带cookie的session对象,响应response,下载图片视频到本地,编码
    1.1自动携带cookie的session对象#session对象----》已经模拟登录上了一些网站---》单独把cookie取出来 -res.cookies-转成字典res.cookies.get_dict()#请求头和数据importrequestsheader={'Referer':'http://www.aa7a.cn/user.php?&ref=http%3A%2F%2......
  • 42. 查找算法
    一、线性查找算法  线性查找是逐一比对,发现有相同值,就返回下标,否则返回-1。这里,我们实现的线性查找是找到一个满足条件的值就返回。/***@brief线性查找**@paramA待查找的数组*@paramN数组的长度*@paramvalue待查找的元素*@returnint如果找到返回......
  • https://www.zhihu.com/tardis/bd/art/627016379?source_id=1001
    1、ODS原始数据层ODS层保存所有操作数据,不对原始数据做任何处理。在业务系统和数据仓库之间形成一个隔离,源系统数据结构的变化不影响其他数据分层。减轻业务系统被反复抽取的压力,由ODS统一进行抽取和分发。记住ODS层数据要保留数据的原始性。处理原则:根据源业务系统表的情况以......
  • 游戏AI-寻路-A*寻路算法
    算法介绍:作用:在一个图中,提供一个起点A与一个终点B,给你找出一条估算出来较短的路时间复杂度:n*log(m),n表示图中的节点数,m表示总边的数量时间复杂度分析:一般游戏中的图是一个二维矩阵,所以每个点的方向也就上下左右这么几个,所以每个点枚举方向的时间为常数虽然复杂度为:n*lo......
  • 数据结构与算法(一)
    需要点Java编程基础常见的数据结构栈(Stack):栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操作。队列(Queue):队列和栈类似,也是一种特殊的线性表。和栈不同的是,队列只允许在表的一端进行插入操作,而在另一端进行删除操作。数组(Array):数组是一种聚合数据......
  • C/C++数据结构与算法课程设计[2023-07-06]
    C/C++数据结构与算法课程设计[2023-07-06]数据结构与算法课程设计一、课程设计的目的、要求和任务 本课程设计是为了配合《数据结构与算法》课程的开设,通过设计完整的程序,使学生掌握数据结构的应用、算法的编写等基本方法。1.课程的目的(1)使学生进一步理解和掌握课堂上所学......
  • 万能欧几里得算法学习笔记
    万能欧几里得算法万能欧几里得算法用于解决一类与\(\left\lfloor\frac{p\cdotx+r}{q}\right\rfloor\)有关的和式求解问题,例如类欧几里得算法中提到的和式就属于此类问题。但万能欧几里得算法从几何意义出发能处理更广泛的和式类型。例如\(\sum_{x=0}^{l}A^xB^{\left\lfloor\f......