HTTPS学习
参考博客
- https://blog.csdn.net/qq_36885515/article/details/123137827
- https://www.cnblogs.com/loleina/p/8418085.html
- https://www.jianshu.com/p/4932cb1499bf
HTTPS的基本概念
HTTPS 是最流行的HTTP 安全形式。它是由网景公司首创的,所有主要的浏览器和服务器都支持此协议。HTTPS 的URL 以https://
,而不是http://
开头,据此就可以分辨某个Web 页面是通过HTTPS 而不是HTTP 访问的。
HTTPS = HTTP + SSL(TLS)
,HTTPS 就是在安全的传输层上发送的HTTP。如下图所示:HTTPS 没有将未加密的HTTP 报文发送给TCP,它在将HTTP 报文发送给TCP 之前,先将其发送给了一个安全层,对其进行加密。现在,HTTP 安全层是通过SSL 及其现代替代协议TLS 来实现的。我们遵循常见的用法,用术语SSL 来表示SSL 或者TLS。
HTTPS与HTTP的区别
HTTPS跟HTTP相比,有以下几个明显的优点:
- 服务器认证(客户端知道它们是在与真正的而不是伪造的服务器通话)
- 客户端认证(服务器知道它们是在与真正的而不是伪造的客户端通话),通常现在web服务,不需要做客户端认证,只需要做服务器认证;
- 完整性(客户端和服务器的数据不会被修改),因为整个传输过程是加密的;
- 加密(客户端和服务器的对话是私密的,无需担心被窃听),使用wireshake监听HTTPS端口会捕获不到数据。
- 效率(一个运行的足够快的算法,以便低端的客户端和服务器使用),如果使用HTTP+特别复杂的数据加密技术来试图替代HTTPS,交互的双方在加解密的过程会消耗大量的性能,性能下降特别明显。
- 普适性(基本上所有的客户端和服务器都支持这些协议)。
- 管理的可扩展性(在任何地方的任何人都可以立即进行安全通信)。
- 适应性(能够支持当前最知名的安全方法)。
- 在社会上的可行性(满足社会的政治文化需要)。
TLS/SSL
早期的互联网协议基本都是不加密进行传输的,如HTTP、FTP、telnet.等协议的
传输层安全性协议(英语:Transport Layer Security,缩写:TLS)及其前身安全套接层(英语:Secure Sockets Layer,缩写:SSL)的历史进程如下表所示:
协议 | 发布时间 | 状态 |
---|---|---|
SSL 1.0 | 未公布 | 未公布 |
SSL 2.0 | 1995年 | 已于2011年弃用 |
SSL 3.0 | 1996年 | 已于2015年弃用 |
TLS 1.0 | 1999年 | 已于2020年弃用 |
TLS 1.1 | 2006年 | 已于2020年弃用 |
TLS 1.2 | 2008年 | |
TLS 1.3 | 2018年 |
SSL/TLS属于哪一层
这个问题十分有意思,从前面的发展历史中我们不难知道,TLS可以视为是SSL的高级版本(主要体现在更加安全上),而从TLS的名字(传输层安全性协议)就会觉得它应该是传输层的协议,当然这可能就望文生义了,实际上在网上有不少的文章在讨论TLS/SSL属于应用层还是传输层,实际上的情况要更为复杂一些
我们知道,网络层有三种划分:OSI模型、TCP/IP模型和五层网络模型,如下图所示:
首先我们对SSL/TLS的作用进行分析:SSL/TLS最初是为了给HTTP协议加密使用,也就是HTTPS协议,通常来说我们可以认为HTTP+SSL/TLS=HTTPS,而实际上现在我们的很多其他应用层协议都可以使用SSL/TLS,比如SSH、FTPS、POP3S、IMAPS等等。再以HTTPS为例,一个HTTPS建立连接需要经过TCP握手建立连接这一步骤的,也就是说HTTPS还是基于TCP的,而TCP属于传输层这是毫无争论的。也就是说从划分最细的OSI七层参考模型来看,SSL/TLS应该是在传输层和应用层之间。
实际上从SSL/TLS的功能来分析:
- SSL Record Protocol(SSL记录协议),它建立在可靠的传输协议(如TCP)之上,SSL/TLS使用了双向字节流传输(全双工),为高层协议提供数据封装、压缩、加密等基本功能的支持,从功能上看这应该是OSI的L6(表示层)
- SSL Handshake Protocol(SSL握手协议):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等,从功能上看这应该是OSI的L5(会话层)
对应五层的网络模型呢?由于OSI模型中的L5、L6、L7都合并成了应用层,所以SSL/TLS应该是属于传输层和应用层了。
对称加密和非对称加密
这一部分我在 哈希函数在区块链中的应用 博客中已经学习过了,但是我们再来加深一边印象
讲到加密,必然需要理解加密算法,而加密算法一般来说可以分为对称加密和非对称加密两种。
这里的对称和非对称是针对加密和解密这两个操作而言的,一般来说是消息发送方发送消息时需要加密,消息接收方在接收消息后需要进行解密。如果加密和解密用的密钥是相同的,则是对称加密;如果不同则是非对称加密。
对称加密
对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。常见的对称加密算法有AES、DES等。
对称加密最大的问题在于密钥的传输:因为如果信息的发送方和接收方是通过网络来进行通信的,而在网络中使用明文通信是不安全的,想要安全通信必须使用密钥加密,同时要保证密钥只有通信双方知道,但是在传输密钥之前双方并没有一个安全可靠双方都知道的密钥。如果最开始的密钥传输过程使用明文,就可能会被别有用心的人截获密钥,之后的加密就毫无意义。
当然,最保险的方法就是线下传输密钥然后再线上通信,可以参考谍战片中的特务舍生取义护送密码本,但是这在互联网时代显然不靠谱。
非对称加密
这时候非对称加密就出现了,非对称加密最大的特点就是把密钥进行分离,将其分成公钥和私钥两个部分,常见的非对称加密算法主要有 RSA 、 DSA 、ECC等。
顾名思义,公钥是可以用在互联网中随意传播的,而私钥则是需要自己小心保存避免泄露的。消息的发送方只需要知道消息接受方的公钥,即可将明文通过公钥加密然后通过网络传输给消息接收方。消息接收方收到密文后,通过非对称加密算法,使用自己的私钥进行解密,即可获取消息内容。
这里面有几个点需要额外关注一下:
- 公钥是所有人都可以获取的,因此想要给接收方发送消息只需要获取公钥即可,所以公钥可以用明文直接传输,因为即使是在传输过程中泄露了公钥,由于解密只能使用私钥,因此整个数据传输也还是安全的
- 在通信过程中一般两边都涉及到消息的发送和接收,因此在通信过程中一般会有两套密钥对
- 可以根据私钥生成公钥,反之不行
- 消息发送方是无法对发送出去的密文解密的,它只能读取自己保存的明文来了解之前发送过的消息
- 如果用私钥加密,由于公钥的信息是在全网传播的,那么在这种情况下是否可以认为非对称加密的意义不大?会有第三方用公钥嗅探的可能?
- 有可能,此时就需要加入时间的因素,我们可以给一个HTTPs定一个会话时间 ,只要这个时间设置的合理,那么及时第三方嗅探到了,当前的会话也早已经结束了
数字签名
场景引入
在通信的过程中,我们使用公钥加密,私钥解密,因为私钥是自己才有的,而传输的信息是不安全的可能被别人截获的,但是只要对其进行加密,然后保证自己才能解密,就可以认为传输信息是安全的。这就好比使用了一个很安全的保险箱来存放重要资料再快递到别的地方去,只要保证只有自己能够解锁保险箱,那么运输过程中保险箱会被谁接触到都不重要,只要保险箱送到目的地就可以了。
即便是非对称加密,也存在一个公钥传输的问题。基本上存在着两种方案,一种是直接把公钥放到网上,然后让需要使用的用户去下载,另一种就是在通信传输过程中,由服务器直接发送给客户端。这两种方法都存在一个问题就是无法保证公钥传输的安全性,虽然公钥是可以给任何人知道的,但是在通信过程中使用的公钥必须是通信双方的公钥,否则如果出现中间人劫持了通信并且将公钥替换为中间人自己的公钥,那么中间人就可以获取到通信内容。
我们设想一个情景:
现在Bob决定给Pat写一份信,信件的内容不用加密,但是要保证Pat收到信件后,能够确认信件的确是Bob发出的,而不是别人冒充Bob发给Pat的,应该如果做呢?
数字签名
首先,Bob将信件通过hash软件计算一下,得到一串消息摘要(有的文章也称之为“hash值”)。这一过程能够保证2点:
过程不可逆。即不能通过消息摘计算出信件的内容。
消息摘要不会重复。即如果信件有任何改动,再次hash计算出的消息摘要一定不会和改动前的消息摘要一致。
然后,Bob使用自己的私钥,将消息摘要加密。加密后的结果,我们称之为“数字签名”。现在,Bob就可以将信件连同数字签名一起发给Pat。
Pat收到信件以后,会做2件事:
- 使用Bob的公钥将数字签名解密,得到信息摘要。如果顺利解密,说明的确是Bob签发的数字签名,不是别人签发的,因为Bob的私钥没有公开。
- Pat使用hash软件对信件再次进行hash计算,和解密数字签名得到的消息摘要对比,如果一致,说明信件没有篡改,确实是Bob发出的。这就是数字签名的过程。它能够确保签名人发出的消息不被篡改,也能证明的确是签名人发出的消息。
通过数字签名,可以保证公钥传输的安全性,如果在路上公钥被人劫持,那么用其他人的公钥是无法顺利解锁Bob的数字签名的。
一切看上去是那么的完美,使用公钥私钥,即能加解密消息,又可以数字签名。
但是,我们再设想一个情况,如果有个坏人Doug, 他要欺骗Pat,冒充Bob给Pat写信,他应该怎么做的?
由于公钥是公开的,并可以导入到电脑,这时候Doug可以偷偷在Pat的电脑上,用自己的公钥替换了Bob的公钥,然后用自己的私钥加密数据,给Pat发送Email。这时候Pat收到的邮件其实是Doug冒充的,但是由于公钥被替换,所以他无法察觉。这时候,该怎么办呢?
数字证书
这时候数字证书的用处就来了,使用数字证书可以确保公钥不被冒充。Bob该如何操作的呢?
首先Bob去找证书中心(CA),为公钥做认证。 CA用自己的私钥,对Bob的公钥和一些相关信息一起加密。生成了数字证书:
- Bob在写给Pat的邮件中,除了数字签名,另外加上了这张数字证书,告诉Pat我的公钥是可信的
- Pat收到Email后用CA的公钥解密这份数字证书,拿到Bob的公钥,然后验证数字签名,后面流程就和图1的流程一样了。由于坏人Doug不能伪造这样一封数字证书(数字证书拥有权威性),也就不能伪装Bob了。
那么,还是有几点疑惑需要解决:
- 假设数字证书被伪造了呢?
- 是的,传输中数字证书有可能被篡改。因此数字证书也是经过数字签名的,上文说道数字签名的作用就是验证数据来源以及数据完整性!Pat收到邮件后可以先验证这份数字证书的可靠性,通过后再验证数字签名。
- 要是有1万个人要给Pat发邮件,难道Pat要保存1万份不同的CA公钥吗?
- 不需要,CA认证中心给可以给B一份“根证书”,里面存储CA公钥来验证所有CA分中心颁发的数字证书。CA中心是分叉树结构,类似于公安部->省公安厅->市级派出所,不管A从哪个CA分支机构申请的证书,B只要预存根证书就可以验证下级证书可靠性。
- 如何验证根证书可靠性?
- 无法验证。根证书是自验证证书,CA机构是获得社会绝对认可和有绝对权威的第三方机构,这一点保证了根证书的绝对可靠。如果根证书都有问题那么整个加密体系毫无意义。
举个例子
数字证书是部署HTTPS认证的网站的必需品,我们在访问一个网站的时候,一般点击浏览器地址栏旁边的小锁就可以看到这时候正在使用的数字证书:
点击进去就可以看到相关的证书信息。证书中包含着十分多的信息,首先最重要的当然是对应的域名和公钥,其他的还有证书的生效时间,使用的加密算法、签名算法等各种相关信息。
小结
签发证书的机构被称为 CA( Certificate Authority),理论上每个人都可以成为CA,因为每个人都可以自己签发证书,但是只有极少数的权威CA颁发的证书才会被承认,这几大权威CA的称为ROOT CA,他们的证书一般都会内置在操作系统中,浏览器默认是信任这些ROOT CA的证书的,而这些ROOT CA下属还有其他的CA,这些下属的CA可以为各种网站颁发证书,根据层层信任的原则,浏览器也会信任这些CA下发的证书,最终就保证了通信中公钥传输的安全。
早期的证书是需要收费的,但是到了近几年加密通信的需求增加,很多网站的运营者并没有那么多钱来购买证书(证书过期了续费也是要钱的),这时候就出现了以Encryption Everywhere、 Let’s Encrypt等为首的CA开始大量普及免费的数字证书,如今国内的很多云厂商也提供了各种免费的数字证书,从而很好的推动了加密通信的发展。不过这些免费的数字证书在安全性上并没有企业级的收费证书那么高,大多数都只是DV证书,如果对安全性有很高的追求,还是建议购买收费的证书。
一般来说数字证书可以按照安全程度分为以下三类:
EV:EV证书(Extended Validation Certificate)是一种根据一系列特定标准颁发的X.509电子证书,根据要求,在颁发证书之前,证书颁发机构(CA)必须验证申请者的身份。不同机构根据证书标准发行的扩展验证证书并无太大差异,但是有时候根据一些具体的要求,特定机构发行的证书可以被特定的软件识别
OV:OV证书(Organization Validation SSL),指需要验证网站所有单位的真实身份的标准型SSL证书,此类证书不仅能够起到网站信息加密的作用,而且能向用户证明网站的真实身份
DV:DV证书(Domain Validation SSL),指需要验证域名的有效性。该类证书只提供基本的加密保障,不能提供域名所有者的信息
TLS加密握手过程
TLS本身是一个混合加密系统,也就是说它使用了对称加密和非对称加密两种方式,首先是使用非对称加密来传输在这次会话过程中生成的用于生成对称加密的密钥( pre-master key),结合明文传输的随机数和算法生成对称加密的密钥之后再使用对称加密进行通信。这样通信的原因是因为非对称加密虽然很安全,但是效率实在是太低了(比对称加密慢几个数量级),因此只用来传输对称加密的密钥,之后就使用效率更高的对称加密来通信。
TLS支持多种密钥交换算法(key exchange algorithms) 和加密算法(ciphersuites),不同的客户端和服务器之间支持的也各不相同,因此在加密通信之间就需要进行协商,客户端和服务端需要协商清楚使用何种算法,使用何种加密方式,使用什么密钥等等问题,这一个过程称为握手过程(handshake)。就好像TCP连接在建立前需要进行三次握手一样,所有的TLS通信在开始之前都需要进行握手(handshake)。当客户端和服务器完成TCP三次握手建立TCP连接之后,就开始进行TLS的握手过程,具体的流程如下:
首先由客户端发送Client Hello 消息到服务器,消息中主要包含了客户端支持的
ciphersuites
, TLS版本信息和客户端随机数,此时是明文传输服务器接收到消息后,返回自己支持的
ciphersuites
, TLS 版本,自己的数字证书和服务器端生成的随机数。注意此时是明文传输客户端开始验证数字证书,可能会不断往上追溯 CA、CA 的 CA、CA 的 CA 的 CA,直到一个授信的 CA。验证完证书之后生成一个新的
pre-master key
,再使用证书中的公钥来对pre-master key
进行加密,然后发送给服务器。注意此时是非对称加密传输服务器接收到客户端发送过来的非对称加密的密文,使用自己的私钥进行解密,获得了
pre-master key
。注意此时是非对称加密传输
到这里为止,服务器和客户端都有三组数字,分别是客户端的随机数、服务器的随机数和pre-master key。其中由于客户端的随机数和服务器的随机数都是使用明文传输,所以这两个数字是有被暴露的风险的,但是由于pre-master key是使用非对称加密传输,十分安全,所以将这三者结合,使用之前协商好的特定的算法就可以生成一个密钥,这个密钥称为shared secert。也就是之后用来对称加密的密钥。
客户端在计算出对称加密的密钥之后,使用该密钥进行对称加密通信,告知服务器之后都使用该密钥进行对称加密。注意此时是对称加密传输
服务器接收到密文后,使用之前计算出的密钥来进行对称解密,解密成功之后,再使用该密钥进行对称加密通信。告知客户端密钥确认无误,可以使用该密钥进行通信。注意此时是对称加密传输
至此,整个TLS的握手过程完整,之后就可以开始对称加密的通信了。
疑问:既然
TLS1.2
纵观整个SSL/TLS协议的发展史,我们可以发现整个SSL/TLS协议就是不断地填坑的一个过程,不断地对旧版本的协议中的各种漏洞进行修补迭代更新,然后发布新的版本,直到TLSv1.2版本才算是一个不错的可用的加密协议版本。即便如此,对应TLSv1.2来说还是有着太多的历史包袱和兼容性的问题,尽管在功能实现上的漏洞可以通过补丁来进行修补,但是在协议设计之初就存在的问题是没有办法修复的,只能推倒重来,于是就出现了后面的TLSv1.3。这里我们先了解一下TLSv1.2版本中的一些主要的问题:
安全问题
作为一个提供安全通信的协议,安全问题是首要的也是致命的问题。TLS发展到1.2以来,已经被很多机构和学者曝出有各种各样的安全漏洞,包括密钥交换算法(key exchange algorithms)、加密套件(ciphersuites)和数字签名(digital signatures)各个方面都存在安全问题,很多都是由于历史原因兼容问题而遗留下来的问题。
还有一些则是设计协议本身就存在的问题如TLS重新协议(renegotiation)可以让心怀不轨的人将高版本的TLS协议重新协商降级到低版本的不安全的协议然后进行攻击。
或者是SNI的不加密问题,TLS1.2及之前的协议都不SNI进行加密,这也存在了很大的风险。
性能问题
互联网上一直存在着加密传输对性能有很大损耗的说法,实际上了解了上面的TLSv1.2握手过程之后,我们可以知道加密传输对性能确实有损耗,但是远没有到很多人鼓吹的那么严重的程度。而且在后面也加入了很多诸如OCSP、HSTS等技术来提高其性能表现,但是即便如此,整个TLSv1.2的握手过程也需要2-RTT,也就是在客户端和服务器之间来回两次才能顺利建立TLS传输,这还是在一切都进行顺利的情况下。
TLS1.3
TLSv1.3是TLS协议更新中变化非常大的一个版本,加入了许多新的特性和性能优化,并且不完全前向兼容,因此也有些人认为应该称为TLSv2.0,不过最后还是命名为TLSv1.3。
针对TLSv1.2中存在的安全和性能问题,TLSv1.3在设计的时候就放弃了前向兼容性,不再对之前的版本进行兼容,同时禁用了大量不安全的算法,使用了少量安全的算法来设计协议,这样的好处就是可以简化握手过程中的操作,使得握手过程从2-RTT变为1-RTT,同时有效提高安全性和性能。
TLS1.3和TLS1.2的主要不同
- 部分新的密码套件(ciphersuite)只能在TLSv1.3中工作,并且TLSv1.3不支持之前在TLSv1.2前用的旧的密码套件ciphersuites。也就是说如果需要使用TLSv1.3就必须要添加新的只能在TLSv1.3中使用的密码套件
- 新的密码套件(ciphersuites)和之前的密码套件定义不同,并不需要指定对应的证书类型(e.g. RSA, DSA, ECDSA) 或者是密钥交换机制 (e.g. DHE or ECHDE)
- TLSv1.3不再支持DSA证书
- TLS1.3中不再支持重新协商(Renegotiation),即不可能像TLSv1.2之前那样通过重新协商来回退到更早的更不安全的版本
- TLS1.3中更多的握手过程都被加密了(Server Hello之后都会进行加密)
- TLSv1.3支持更多的的消息类型,即对自定义的扩展API和认证传输有更好的扩展性
客户端在TLS握手阶段发送ClientHello数据包的时候需要提供支持的密码套件(ciphersuite)和密钥共享(key_share)从而提高速度,如果client发送的keyshare类型是server不支持,那就不是1-RTT。
sessions会话在TLS握手完成之后才会建立,所以在session和TLS握手之间可能会有空隙(即不是连续的)
TLS1.3中的密钥交换算法
TLS 1.3的核心宗旨是简单性。在新版本中,除去了Diffie-Hellman(DH)密钥交换以外的所有密钥交换算法。TLS 1.3还定义了一组经过测试的DH参数,无需与服务器协商参数。由于只有一个密钥交换算法(具有内置参数)和少数支持的密码,因此设置TLS 1.3通道所需的绝对带宽比早期版本要少得多。
我们来看DH算法交换密钥的步骤。假设客户端和服务器双方需要传递密钥,他们之间可以这么做:
- 客户端首选选择一个素数p,例如509; 底数g,任选,例如5 ; 随机数a,例如123; 然后计算A=$g^a \mod p$,结果是215,然后,客户端发送p=509,g=5,A=215给服务器;
- 服务器收到后,也选择一个随机数b,例如,456,然后计算$B=g^b \mod p$,结果是181,服务器再同时计算$s=A^b \mod p$,结果是121;
- 服务器把计算的B=181发给客户端,客户端计算$s=B^a \mod p$的余数,计算结果与服务器算出的结果一样,都是121。
所以最终双方协商出的密钥s是121。注意到这个密钥s并没有在网络上传输。而通过网络传输的p,g,A和B是无法推算出s的,因为实际算法选择的素数是非常大的。所以,更确切地说,DH算法是一个密钥协商算法,双方最终协商出一个共同的密钥,而这个密钥不会通过网络传输。
TLS1.3握手过程
整个流程的目的和TLS 1.2是相似的,TLS握手过程就是为了让双方能够得到一个安全的可用于对称加密的密钥。和之前不一样的就是,无非就是客户端提前把所有的公钥计算了一遍,发给server,server再挑选。