SSL(Secure Sockets Layer)最初由Netscape定义, 分别有SSLv2和SSLv3两个版本(SSLv1未曾对外发布); 在SSLv3之后SSL重命名为TLS。
协议 | 时间 | 建议 | 说明 |
---|---|---|---|
SSLv1 | / | / | 实际从未公开发布 |
SSLv2 | 1995 | 弃用 | IETF已于2011年弃用 |
SSLv3 | 1996 | 弃用 | IETF已于2015年弃用 |
TLSv1.0 | 1999 | 兼容 | - |
TLSv1.1 | 2006 | 兼容 | - |
TLSv1.2 | 2008 | 主推 | 目前最新可用版本 |
TLSv1.3 | / | / | 2016开始草案制定 |
证书校验
1、CA机构颁发给服务器的数字证书中包含哪些内容?
至少包含了向CA机构申请证书时的“个人信息”, “证书有效期”、“证书的公钥”、“CA机构给到证书的数字签名”、“CA机构信息”等
打开*.crt文件,可以看到重要的比如,域名、公钥。
2、浏览器如何验证证书?
首先, 浏览器利用证书中指定的hash算法如sha256对”明文信息”计算出信息摘要(摘要就是对明文信息计算sha256值)
然后,利用CA证书的公钥来解密数字证书中的”数字签名”(数字签名是CA机构的私钥对摘要的加密),解密出来的数据也是信息摘要。
最后,判定两个摘要信息是否相等就行。
如何证明CA证书本身不是伪造的呢?
简单粗暴的方案是:操作系统内置所有CA机构的证书,且假设这个操作系统没有被恶意入侵。
折中方案是:把CA机构分成两类,根CA和中间CA, 我们通常向中间CA申请证书,根CA主要给中间CA做认证用。
中间CA又可以给其它中间CA认证,形成树状结构,一级级认证,直到找到根证书。
证书上都有证书链,能找到上一级机构是什么,使用与上一步相同的算法,让上一级机构证实当前证书的真实性,直到追溯到根证书,
而根证书只需要在操作系统中可查找到就任务是对的,因为根证书是行业内浏览器和操作系统厂商的规范。
如何检验根证书的合法性?
根证书在安装操作系统时内置了。浏览器查找根证书是否存在操作系统里面,若不是则不合法,反之则合法。
自签名的CA证书,需要用户提前内置证书在用户电脑文件中,或者放置在服务器上。
根证书就是一种特殊的自签名证书。
CA签发证书的过程:
首先 CA 会把持有者的公钥、域名、颁发者、有效时间等公开信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
最后将 Certificate Signature 添加在文件证书上,形成数字证书;
客户端校验服务端的数字证书的过程:
首先客户端会使用同样的 Hash 算法把证书上面公开信息(跟CA签名项一样)计算 Hash 值 H1(数字摘要);
通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2(数字摘要)。
最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
以下过程均省略了证书校验
一、RSA密钥交换算法
传统的 TLS 握⼿基本都是使⽤ RSA 算法来实现密钥交换的。在 RSA 密钥协商算法中,客户端会⽣成随机密钥,并使⽤服务端的公钥加密后再传给服务端。根据⾮对称加密算法,公钥加密的消息仅能通过私钥解密,这样服务端解密后,双⽅就得到了相同的密钥,再⽤它加密应⽤消息。
RSA算法流程文字描述如下:
(1)任意客户端对服务器发起请求,服务器首先发回复自己的公钥到客户端(公钥明文传输)。
(2)客户端使用随机数算法,生成一个密钥S,使用收到的公钥进行加密,生成C,把C发送到服务器。由于攻击者没有服务器的私钥,所以无法解密会话密钥。
(3)服务器收到C,使用公钥对应的私钥进行解密,得到S。
(4)上述交换步骤后,客户端和服务器都得到了S,S为密钥(预主密钥)。
至此双方完成连接,接下来服务器端和客户端可以使用对称加密算法和会话密钥S加密解密数据。
图示如下:
SSL协议中,服务器发送的公钥在SSL中是通过certificate报文发送的,certificate中的包含了公钥。C是通过Client key exchange报文发送的。
RSA密钥协商算法有几个优点:
每次连接阶段的会话密钥是不同的,无须存储到设备中,连接关闭后会话密钥就会消失。
每次连接中的会话密钥是不同的,避免了烦琐的会话密钥分配问题。
虽然RSA运算很慢,但由于会话密钥长度相对很小,计算的数据量并不大,所以性能消耗相对可控。
这个方案用途非常广泛,HTTPS本身也是借鉴了这个方案,只是在设计上更严谨。
RSA密钥协商算法也有缺点:
获取会话密钥过程其实并不能称为协商,完全是由客户端决定的,只能称为密钥传输。
如果客户端生成会话密钥没有使用标准的算法,可能会带来安全隐患。
比如说客户端每次随机从26个字母中选取4个字母作为会话密钥,那么很容易受到暴力攻击。
攻击者不会去破解RSA加密算法的私钥,直接暴力破解会话密钥S就能反解出明文。
另外一个最大的问题就是不能提供前向安全性。
使用 RSA 密钥协商算法的最⼤问题是不⽀持前向保密。
因为客户端传递随机数(⽤于⽣成对称加密密钥的条件之⼀)给服务端时使⽤的是公钥加密的,服务端收到到后,会⽤私钥解密得到随机数。
所以⼀旦服务端的私钥泄漏了,过去被第三⽅截获的所有 TLS 通讯密⽂都会被破解。
前向安全性:过去所有数据包都被中间人抓取,包括tls握手过程中传输的随机字符串,只是没有密钥,但是这些数据包被中间人保留下来了,
如果有一天服务器端私钥泄漏,这些包全都可以解密。
为了解决这⼀问题,于是就有了 DH 密钥协商算法
二、DH密钥协商算法
Diffie-Hellman算法,简称DH算法,是Whitfield Diffie和Martin Hellman在1976年公布的一个公开密钥算法,它的历史比RSA公开密钥算法更悠久。
使用RSA密钥协商算法传输会话密钥的时候,会话密钥完全由客户端控制,并没有服务器的参与,所以叫作密钥传输。
而DH算法确切地说,实现的是密钥交换或者密钥协商,DH算法在进行密钥协商的时候,通信双方的任何一方无法独自计算出一个会话密钥,
通信双方各自保留一部分关键信息,再将另外一部分信息告诉对方,双方有了全部信息才能共同计算出相同的会话密钥。
客户端和服务器端协商会话密钥的时候,需要互相传递消息,消息即使被挟持,攻击者也无法计算出会话密钥,
因为攻击者没有足够的信息(通信双方各自保留的信息)计算出同样的会话密钥。
1、在使用DH算法之前,先要生成一些公共参数p和g,这些参数在协商密钥之前必须发给对端。
2、通信双方的任何一方可以生成公共参数p和g,这两个数是公开的,被截获了也没有任何关系,一般情况下由通信双方的服务器端计算。p是一个很大的质数,建议长度在1024比特以上,这个长度也决定了DH算法的安全程度,g表示为一个生成器,这个值很小,可以是2或者5。通过参数,服务器端和客户端会生各自生成一个DH密钥对,私钥需要保密。
3、客户端连接服务器端,服务器端将参数发送给客户端。
4、客户端根据公开参数生成一个随机数a,这个随机数是私钥,只有客户端知道,且不会进行发送,然后计算A = (g ^ a) mod p, A就是公钥,需要发送给服务器端。
5、服务器端根据公开参数生成一个随机数b,这个随机数是私钥,需要服务器端保密,然后计算B = (g ^ b) mod p, B是公钥,需要发送给客户端。
6、客户端发送A数值给服务器端,服务器端计算K = (A ^ b) mod p。
7、服务器端发送B数值给发送方,客户端计算K = (B ^ a) mod p。
8、服务器端和客户端生成的Z就是会话密钥,协商完成。
这里的关键点就是私钥a和b不应该泄露,分别由通信双方维护,另外A和B进行互换才能完成协商,这两个值被截获对攻击者来说没有任何价值。
换句话说,只要私钥不发生泄露,攻击者即使有了A和B也不会计算出会话密钥。
因为在DH密钥协商算法中,服务器的公私密钥是固定的,只有客户端的公钥是会话时当即随机生成,所以安全隐患很大,也就被废弃了!
DH密钥协商算法缺点:
前向安全性问题:DH密钥协商是对称密钥交换的一种方法,但它无法提供前向安全性。
这意味着一旦攻击者获取到之前的密钥材料,他们可以解密之前的通信内容。
中间人攻击:DH密钥协商在不同参与者之间交换公钥的过程中存在中间人攻击的风险。
攻击者可以冒充通信的一方,与另一方分别建立连接,并将两个独立的密钥交换过程相互连接起来,使得两个通信方认为他们建立了私密通信,但实际上所有的信息都被攻击者所掌握。
当然可以使用证书公钥加密传输参数就解决中间人工具问题了。
三、DHE密钥交换算法
DH算法分类标准有两类:第一种是基于密钥;第二类基于计算方式。
静态DH是指:通信双方有一方的私有密钥是固定的,另一方临时生成,一般是服务器端固定。
但是这样随着时间的验证,很容易被破解,而一旦被破解,之前所有的通讯数据都很容易被解密,不具备前向安全的特性。目前静态DH基本不用。
既然静态DH算法中,一方固定一方临时生成的方式不安全,那么我们就双方都不固定。
通讯双方的私有密钥都采用临时生成的方式,这中DH算法称之为DHE算法(E是指Ephemeral, 临时的)。
DHE(E全程为ephemeral(临时性的)):
既然固定⼀⽅的私钥有被破解的⻛险,那么⼲脆就让双⽅的私钥在每次密钥交换通信时,都是随机⽣成的、临时的,这个⽅式也就是 DHE 算法。
所以,即使有个⽜逼的⿊客破解了某⼀次通信过程的私钥,其他通信过程的私钥仍然是安全的,因为每个通信过程的私钥都是没有任何关系的,都是独⽴的,这样就保证了「前向安全」。
按照计算方式又可以分为:模指数DH算法和椭圆曲线DH算法。
模指数是指:指数运算+取模运算,前面介绍的便是这种DH算法。但是这种算法由于涉及指数运算,计算量开销非常的大,
于是后来出现了椭圆曲线计算方式,据说这种方式计算量小了很多。
IPSec中的DH算法绝大多数是模指数DH算法,
SSL/TLS中采用的椭圆曲线DH算法。即ECDH算法
四、ECDHE密钥交换算法
ECDHE是DH算法的一种变体。
它使用椭圆曲线密码学来实现密钥交换过程。与传统的DH算法相比,ECDHE在提供相同的安全性的同时,具有更高的效率和较短的密钥长度。
因此,ECDHE在现代的安全通信协议中被广泛使用,特别是在SSL/TLS协议中用于建立安全的HTTPS连接。
DHE 算法由于计算性能不佳,因为需要做⼤量的乘法,为了提升 DHE 算法的性能,所以就出现了现在⼴泛⽤于密钥交换算法 —— ECDHE 算法。
ECDHE 算法是在 DHE 算法的基础上利⽤了 ECC 椭圆曲线特性,可以⽤更少的计算量计算出公钥,以及最终的会话密钥。
ECC(椭圆曲线密码学):椭圆曲线密码学(Elliptic curve cryptography),简称ECC,是一种建立公开密钥加密的算法,也就是非对称加密。类似的还有RSA,ElGamal算法等。ECC被公认为在给定密钥长度下最安全的加密算法。比特币中的公私钥生成以及签名算法ECDSA都是基于ECC的。
https://blog.csdn.net/u014644574/article/details/131861982
下面通过一个故事来叙述一下ECDHE密钥协商算法的原理
小红和小明使用 ECDHE 密钥交换算法的过程:
双⽅事先确定好使⽤哪种椭圆曲线,和曲线上的基点 G,这两个参数都是公开的;
双⽅各⾃随机⽣成⼀个随机数作为私钥d,并与基点 G相乘得到公钥Q(Q =dG),此时⼩红的公私钥为 Q1和 d1,⼩明的公私钥为 Q2 和 d2;
双⽅交换各⾃的公钥,最后⼩红计算点(x1,y1) = d1Q2,⼩明计算点(x2,y2) = d2Q1,由于椭圆曲线上是可以满⾜乘法交换和结合律,
所以 d1Q2 = d1d2G = d2d1G = d2Q1 ,
因此双方的 x 坐标是⼀样的,所以它是共享密钥,也就是会话密钥。
这个过程中,双方的私钥都是随机、临时⽣成的,都是不公开的,即使根据公开的信息(椭圆曲线、公钥、基点G)也是很难计算出椭圆曲线上的离散对数(私钥)。
ECDHE秘钥协商算法的TSL握手:
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」消息。
这个过程服务器做了三件事:
选择了名为 named_curve 的椭圆曲线,选好了椭圆曲线相当于椭圆曲线基点 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 请求和响应了。
由于ECDHE的背后使用的数学原理是椭圆曲线,所以在安全性和速度上都较传统的使用离散对数的DH算法有了不少的提高,ECDHCE能够使用较少的密钥位数实现传统DH算法高密钥位数的安全,在ECC椭圆曲线数学问题衍生出来的多个安全算法,如ECC非对称加密,ECDSA签名算法,都在加密位数、速度和安全上有了很大的提升,但是因为随机生成器可能留有后门以及一些其他的因素,使得ECC相关的衍生算法没有完全盖过RSA的风头。
以下是抓包示例
客户端发出请求(Client Hello), 提供给服务端以下信息:
TSL 1.2、以及16种密码套件、随机数、Session ID
服务端回应(Server Hello), 提供给客户端以下信息
可以看到服务端提供了类似信息, 只支持TLS_CHACHA20_POLY1305_SHA256
参考:
密钥协商算法的演变 —— RSA算法 - DH算法 - DHE算法 - ECDHE算法_故里有长安丶丶的博客-CSDN博客