前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官你不要说我不懂TLS握手了

面试官你不要说我不懂TLS握手了

作者头像
shysh95
发布2021-11-25 14:11:24
5340
发布2021-11-25 14:11:24
举报
文章被收录于专栏:shysh95shysh95

摘要

  1. 基于RSA密钥协商算法的TLS1.2握手分析
  2. 数字证书
  3. DHE和ECDHE算法
  4. 基于ECDHE密钥协商算法的TLS1.2握手分析

TLS握手时采用的加密方式

非对称加密和对称加密。

非对称加密主要用来保护对称加密密钥交换的安全性,一旦客户端和服务端交换密钥完成,即可使用密钥采用对称加密的方式进行通信。

基于RSA密钥协商算法的TLS1.2握手分析

TLS握手的总过程

TLS1.2握手的过程由于本人本地密码套件不支持,相关图片来源于网络。

  • 第一次握手客户端的发起的ClientHello请求
  • 第二次握手ServerHello,发送相关信息和证书给客户端
  • 第三次握手客户端发送请求给服务端
  • 第四次握手服务端响应客户端的第三次握手

客户端的ClientHello

  • Version:客户端使用的TLS的版本号,这里是1.2
  • Random:随机数,这个随机数会被服务端保留,后续用来生成对称密钥
  • CipherSuites:支持的加密方式列表

服务端的ServerHello

  • version:确认支持TLS的版本,这里为1.2
  • Random:服务器端的随机数,此随机数后续用来生成对称密钥
  • Cipher Suite:确认使用的加密算法

Cipher Suite的格式

Cipher Suite虽然很长,但是它是一个固定格式,基本的格式为:

密钥交换算法 + 签名算法 + WITH + 对称加密算法 + 摘要算法。

比如上图中的我们的使用的算法分别为:

  • 密钥交换算法:RSA
  • 证书的签名验证算法:RSA(这里由于WITH前面只有一个RSA,所以签名算法也是RSA)
  • 握手后的通信对称加密算法:AES对称算法,密钥长度为128位,分组模式是GCM
  • 摘要算法:SHA256

服务端如何证明自己的身份

服务端为了证明自己的身份会发送Server Certificate给客户端,这个消息里面包含数字证书。具体信息如下:

除了发送了证书,服务端还发送了Server Hello Done消息,目的是告诉客户端你要的东西我都给你了。具体内容如下:

TLS第三次握手

客户端在验证证书无误后,会发起第三次握手请求,首先会发送Client Key Exchange消息,内容如下:

客户段会生成pre-master随机数,并使用服务端RSA公钥进行加密发送给服务器,Encrypted PreMaster就是经过加密后的随机数,服务器收到后可以使用私钥解密。

至此,客户段使用三个随机数可以生成会话密钥了,于是生成会话密钥以后会发送一个Change Cipher Spec消息告诉服务端开始使用加密的方式传输。

最后客户端会发送一个Encrypted HandShake Message,这个就是把之前的数据做个摘要,然后再用会话密钥加密发送给服务器,供服务器验证。

TLS第四次握手

第4次握手其实就是服务器发送个Change Cipher Spec消息(由于服务器收到了第三个随机数,因此也可以生成会话密钥,后续可以加密传输了)和个Encrypted HandShake Message消息,握手完成。

可以看出,Change Cipher Spec之前的消息都是明文传输,之后都是通过对称密钥加密传输。

数字证书

数字证书包含的内容

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

数字证书如何签发

  1. CA会对持有者的公钥、用途、有效时间等信息打成一个包,然后对着信息进行计算,获得一个hash值
  2. CA会使用自己的私钥将该hash值加密,生成签名
  3. 最后将签名添加在文件证书上,形成数字证书

客户端如何校验服务端的数字证书

  1. 客户端使用相同的算法计算服务器数字证书的hash值(假设这里的代号为H1)
  2. 由于浏览器和操作系统集成了CA的公钥信息,浏览器在收到证书后通过CA进行解密签名内容获得一个hash值(H2)
  3. 比较H1和H2的值,相同证书可信,否则不可信

证书链是啥

我们向CA申请的证书一般都不是由根证书签发,而是由中间证书签发,比如上述思否(segmentfault.com)的证书,证书有三级。

那么具体的验证过程如下:

  • 客户端在收到思否(segmentfault.com)的证书以后,发现证书的签发者不是根证书,因此无法根据本地已有根证书中的公钥去验证segmentfault.com是否可信。因此客户端需要找到该证书的签发者DigiCert TLS RSA SHA256 2020 CA1,然后向该CA请求中间证书
  • 请求到DigiCert TLS RSA SHA256 2020 CA1证书以后,发现它还不是根证书,但是它的上级签发机构DigiCert Global Root CA已经没有上级,说明DigiCert Global Root CA是根证书。此时应用软件会检查DigiCert Global Root CA证书是否已经预载到系统中,如果有可以根据证书中的公钥验证DigiCert TLS RSA SHA256 2020 CA1证书,验证通过则认为中间证书可信。
  • DigiCert TLS RSA SHA256 2020 CA1证书被信任以后,可以使用它包含的公钥去验证思否(segmentfault.com)的证书,验证通过则信任该证书。

从上图中可以看出思否证书的签发根证书DigiCert Global Root CA已经在我的MacOS操作系统中预置。

DHE和ECDHE算法

RSA密钥协商算法的缺陷

由于我们的客户端传递随机数都是使用公钥加密,服务端收到后使用私钥解密。所以一旦我们服务器的私钥遭到泄漏,我们就可以对过往截获服务器客户端的TLS报文进行解密(无法向前保密)。

今日截获数据,明日(或未来)解密数据。

RSA有缺陷如何解决

RSA密钥协商算法既然无法向前保密,后面使用了新的协商算法:

  • DH
  • DHE
  • ECDHE

DH算法是什么?

DH算法是非对称加密算法,因此也可用作密钥交换,核心思想就是离散对数。

代码语言:javascript
复制
# 对数运算

x = log2y

上述公式其中x为对数,y为真数,底为2。对于上述例子,32的对数是5,64的对数是6,可以看出对数的取值是能够连续的。

但是离散对数的取值是无法连续,离散也是因此得名。

代码语言:javascript
复制
a ^ i (mod p) = b

对于一个整数b和一个质数p的一个原根a,能够找到唯一一个指数i使得上述公式成立,那么指数i称为b的以a为底数的模p的离散对数。

底数a和和模p是离散对数的公开参数,b是真数,i是对数,知道了对数i我们很轻松就能算出真数b,但是如果知道真数b但是很难计算对数i,尤其是模p很大的时候,现有的计算机的计算能力是无法破解的。

DH算法如何交换密钥

  1. 客户端(称为小c)和服务端(称为小s)需要交换密钥,首先需要确定公开参数底数g和模p。
  2. 客户端小c和服务端小s分别生成一个随机数作为私钥(分别称为小a和小b),在根据底数a和模p即可计算出各自的公钥(称为大A和大B):

小c的公钥为A:A = g ^ a (mod p) 小s的公钥为B: B = g ^ b (mod p)

可以看出我们通过私钥生成公钥很容易,但是通过公钥逆向计算私钥绝对是地狱级别的困难,如果您能算出来说不定你就是未来量子(手动狗头)。

双方交换公钥以后,客户端小c有:

  • A:客户端公钥
  • a:客户端私钥
  • B:服务端公钥
  • g
  • p

服务器端小s有:

  • A:客户端公钥
  • b:服务端私钥
  • B:服务端公钥
  • g
  • p

客户端小c会做以下计算:

K = B ^ a (mod p)

服务端小s会做以下计算:

K = A ^ b (mod p)

由于离散对数具有幂的交换律,因此客户端和服务端计算出来的K值就是相等的,这个K就是对称加密密钥。

DH算法的种类

目前有两种:

  • static DH
  • DHE

static DH就是有一方私钥固定不变(通常为服务器端),虽然很难破解但是随着时间的推移还是有一定几率被破解的,不具备向前保密。

DHE就是让每次双方在进行密钥协商时,都随机生成私钥,这样每次通信过程都是独立的,即使你破解了此次的私钥,也无法破解过往的通信。

ECDHE算法是啥?

在DHE算法的基础上利用了ECC椭圆曲线的特性,用更少的计算量计算公钥。

为什么需要ECDHE算法

DHE算法由于需要大量的乘法运算,计算性能不高,所以出现了ECDHE算法来替代他。

ECDHE算法密钥交换过程

  1. 客户端和服务端确定好使用哪种椭圆曲线以及曲线上的基点G,这个对外公开
  2. 客户端和服务端各自生成一个私钥(假设分别为c和s),将私钥与基点G相乘可以分别得到其公钥(假设分别为CP和SP)
  3. 双方交换公钥,最后服务器计算(x1,y1)= CP * s,客户端计算(x2,y2)= c * SP,由于椭圆曲线的满足交换律和结合律,所以(x1, y1)= CP * s = s * c * G = c * s * G = c * SP = (x2, y2),因此(x1,y1)和(x2, y2)相等,这个坐标即可当做对称密钥。

基于ECDHE密钥协商算法的TLS1.2握手分析

客户端发起第一次握手请求这个采用RSA协商算法的握手无区别,这里就不说了。

TLS第二次握手

当服务端进行响应,进行第二次握手就可以有区别了,主要有两步如下图:

首先回应ServerHello消息,如下:

这里使用TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256密码套件,说明我们的密钥协商算法要使用ECDHE。

然后第二步中先是发送证书给客户端以示清白,紧接着这里就和之前RSA密钥协商的TLS握手有区别了,这里会发送Server Key Exchange的消息,我们看一下消息内容:

  • Curve Type:选取了名为named_curve的椭圆曲线,选好椭圆曲线相当于基点G也好了
  • Pubkey:根据基点G和服务器生成的私钥计算出的公钥
  • Signature:为了保证这个椭圆曲线的公钥不被第三方篡改,服务端会用RSA签名算法给服务端的椭圆曲线公钥做个签名。

最后服务端在发送一个Server Hello Done消息,告诉客户端这是我提供的信息。

目前客户端和服务端已经共享了两个随机数、使用的椭圆曲线,椭圆曲线基点G,服务器的椭圆公钥

TLS第三次握手

这一步客户端会发送Client Key Exchange消息,消息如下:

  • Pubkey:客户端根据服务端共享的曲线、基点加上自己的私钥计算出的公钥,该公钥会共享给服务器使用

到这里服务器和客户端又多共享了客户端公钥,按道理已经可以计算出对称密钥了,但最终的会话对称密钥为了更加安全是使用「客户端随机数 + 服务器随机数 + 椭圆曲线计算出来的共享密钥」来生成最终的会话密钥。

算好会话密钥以后,紧接着会发送一个Change Cipher Spec消息告诉服务段后续的数据我会通过会话对称密钥加密传输。

最后会发送Encrypted Handshake Message,这部分消息就是对之前发送的数据做个摘要,然后使用对称密钥加密以后传输给服务器。

第三次握手以后,不需要等待服务器的第四次握手既可以进行传输应用数据,如下图:

TLS第四次握手

服务器在收到客户端的请求后,也会发送Change Cipher Spec消息和Encrypted Handshake Message。

至此握手完成,以后数据就可以正常加密传输了。

ECDHE和RSA密钥协商算法的区别

  • RSA不支持向前保密,ECDHE支持向前保密
  • ECDHE在三次握手结束以后就可以传输应用数据,节省了一个消息的往返时间,RSA必须等待四次握手结束后才可以传输应用数据
  • ECDHE在第二次握手会发送Server Key Exchange的消息,RSA没有该消息。

目前TLS已经发展到1.3,1.3对比1.2也有了很多优化,有兴趣的读者可以去了解一下。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
SSL 证书
腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档