Web技术(三):TLS 1.2/1.3 加密原理(AES-GCM + ECDHE-ECDSA/RSA)

前言

前篇博客:图解HTTP中谈到,HTTP/1.1 协议默认是以明文方式传输数据的,这就带来三个风险:窃听风险、假装风险、篡改风险。HTTP 协议自身没有加密机制,但能够经过和 TLS (Transport Layer Security) / SSL (Secure Socket Layer) 的组合使用,加密 HTTP 的通讯内容,借助 TLS / SSL 提供的信息加密功能、完整性校验功能、身份验证功能保障网络通讯的安全,与 TLS / SSL 组合使用的 HTTP 被称为 HTTPS(HTTPSecure),能够说 HTTPS 至关于身披 SSL / TLS 外壳的 HTTP。
HTTPS协议分层模型
近几年,网络安全问题愈来愈受重视,国内外各大互联网公司好比Google、Baidu、Facebook等,都在不谋而合地开始大力推行 HTTPS,为鼓励全球网站的 HTTPS 实现,一些互联网公司都提出了本身的要求:git

  • Google 已调整搜索引擎算法,让采用 HTTPS 的网站在搜索中排名更靠前;
  • 从 2017 年开始,Chrome 浏览器已把采用 HTTP 协议的网站标记为不安全网站;
  • 苹果要求 2017 年 App Store 中的全部应用都必须使用 HTTPS 加密链接;
  • 当前国内炒的很火热的微信小程序也要求必须使用 HTTPS 协议;
  • 新一代的 HTTP/2 协议的支持需以 HTTPS 为基础。

所以,咱们要开发网络应用,也应该跟上全网 HTTPS 的潮流,使用 HTTPS 协议为咱们的数据安全上一把锁。前一篇博客已经详细介绍了 HTTP 协议,下面重点介绍网络安全通讯协议 TLS / SSL。web

1、TLS 加密原理

SSL(Secure Socket Layer) / TLS(Transport Layer Security) 是独立于 HTTP 的协议,因此不光是 HTTP 协议,其余运行在应用层的 SMTP 和 Telnet 等协议都可配合 SSL / TLS 协议使用,能够说 SSL / TLS 是当今世界上应用最为普遍的网络安全技术。算法

Netscape 开发了原始的 SSL 协议,SSL 1.0 由于存在严重的安全缺陷从未公开发布,SSL 2.0于 1995年发布,但其中仍包含许多安全缺陷,因而在1996年发布了SSL 3.0。随着加密与解密安全攻防战的博弈,SSL 协议的安全性逐渐知足不了需求,SSL 2.0 在 2011 年被RFC 6176弃用,SSL 3.0 于 2015 年被RFC 7568弃用。小程序

TLS 1.0 在 1999 年发布于RFC 2246中,TLS 1.0 和 SSL 3.0 之间的差别并不显著(TLS 1.0 等同于 SSL 3.1),更名主要是为了和Netscape撇清关系(SSL协议由Netscape主导开发),表示一个新时代的来临(TLS协议由 IETF 进行标准化)。微信小程序

随着网络攻击技术的发展,TLS 加密算法也须要进行升级,TLS 1.1 于 2006 年在RFC 4346中定义,TLS 1.2 于 2008 年在RFC 5246中定义,并于2011年在RFC 6176中完成优化,最新版本的TLS 1.3 于 2018 年在RFC 8446中定义。早在2018年10月,苹果、谷歌、微软和Mozilla就联合宣布,将在2020年3月弃用TLS 1.0和TLS 1.1(当你读到本篇博客时,TLS 1.0和TLS 1.1 已经被弃用),因为 TLS 1.3 才发布没多久,将来几年内 TLS 1.2 将成为网络安全协议的主流(HTTP/2协议便使用TLS 1.2+版本做为安全加密层)。
SSL/TLS协议发布时间与网站支持率对比浏览器

1.1 TLS 信息加密

早在几千年前,人们就有了对信息加密的需求和实践,最初人们只是将完整信息隐藏,后来将字符进行移位变换处理以隐藏原来的意思(能够参考博客:谍战中的古典密码学)。随着上世纪计算机的诞生和数学的进步,将有效信息编码为二进制数据,并对这些二进制数据进行数学运算处理的现代密码学得到了飞速发展(能够参考博客:区块链中的现代密码学)。安全

现代密码学根据密钥不一样,能够分为对称密钥加密法和非对称密钥加密法,两者区别对好比下:性能优化

类别 对称密钥加密法 非对称密钥加密法
特色 加密和解密使用相同的的密钥 加密和解密使用成对的公钥和私钥,
可使用公钥解密私钥解密(信息加密),
也可使用私钥加密公钥解密(数字签名)
优势 加密和解密的效率高(比非对称加密效率高几百倍),适合大数据量加解密 不须要交换密钥,安全性更强,还可用于身份认证
缺点 双方须要交换密钥,密钥的安全没法保证 加密和解密的效率低(只有对称加密效率的几百分之一),不适合大数据量加解密
经常使用算法 DES、3DES、IDEA、AES RSA、DSA、ECC、Diffie-Hellman

从上面的对比能够看出,Web的数据量仍是比较大的,对Web数据信息进行加密适合选择对称密钥加密法。但对称密钥加密法有个缺陷,通讯双方须要交换密钥,密钥的安全无法获得保证,这就须要借助非对称密钥加密法来交换密钥了。TLS 也正是采用相似的策略,经过非对称密钥加密法来交换会话密钥,经过对称密钥加密法来加密信息。
TLS混合密钥加密过程
咱们先看对Web信息加密使用的对称密钥加密法,按照加密方式不一样能够将对称密码分为两大类:序列密码(流密码) 和分组密码(块密码),两者的区别对好比下:服务器

类别 序列密码 / 流密码 分组密码 / 块密码
特色 以最小单位比特做为一次加解密的操做元素,采用设计好的算法对明文数据流进行加密与解密操做 将明文分为若干长度固定的组块(长度不足的组块按特定格式填充),以每一个组块做为一次加解密的操做元素,采用设计好的算法对明文数据组块进行加密与解密操做
优势 速度快,便于硬件实现,错误传播较轻 统计特性优良,修改敏感
缺点 统计混乱不足,修改不敏感 速度慢,错误传播严重
经常使用算法 WEP、RC四、ChaCha20 DES、3DES、IDEA、AES

流密码算法是以“一次性密码本“为雏形演变出来的加密算法,一次性密码本算法很重要的一个特性就是密钥使用的”一次性“,流密码算法安全性的关键也在于毫不第二次使用相同的密钥,这就须要能产生大量的随机数。流密码使用伪随机数发生器产生一次性密钥流,能够说流密码的安全性取决于伪随机数发生器的性能,高性能的伪随机数发生器(一个硬件模块)也能够构建出强度较高的流密码算法。咱们通常使用的计算机并无专门提供高性能的伪随机数发生器硬件模块,因此使用流密码算法的比较少(流密码算法便于硬件实现,通常在专门设计有伪随机数发生器的平台上使用),更经常使用的是分组密码算法。微信

分组密码的每一个组块加解密相似于流密码,每一个组块的长度能够做为衡量加密强度的一个指标,如今通常采用128位、192位、256位的组块长度(须要平衡加密强度与加密效率,随着处理器计算能力提高也会同步提高加密强度)。DES(Data Encryption Standard)是1977年美国联邦信息处理标准(FIPS)种所采用的一种对称密码(3DES是其三重加密加强版),目前已能在短期内被破解。如今推荐使用的对称加密算法是AES(Advanced Encryption Standard),该算法是在2001年经过全世界范围内公开竞争方式选拔出来的,Rijndael 算法最终力压群雄被美国国家标准技术研究所(NIST)选定为AES标准。

分组密码的关键特性是每一个组块都使用不一样的组块密码,这些组块密码能够有相关性,也即后一组的密码能够经过前一组的密码迭代而来(分组密码靠迭代关系下降了对伪随机数发生器的性能需求)。根据分组密码迭代方式的不一样,产生了多种不一样的分组密码模式,常见的有五种模式ECB、CBC、CFB、OFB、CTR。这五种分组密码模式就不一一介绍了,这里主要介绍两种经常使用的模式:CBC(Cipher Block Chaining mode)和CTR(Counter mode),两者的主要区别对好比下:
CBC与CTR分组密码模式对比

类别 CBC(Cipher Block Chaining mode) CTR(Counter mode)
特色 首先将明文分组与前一个密文分组进行XOR异或运算,而后再进行加密;加密第一个分组时,使用一个随机产生的初始化向量 IV(Initialization Vector)来代替前一个密文分组 每一个分组对应一个逐次累加的计数器,并经过对计数器加密生成分组密码;最终的密文分组是经过将计数器加密获得的密钥流与明文分组进行XOR异或运算获得的
优势 明文的重复排列不会反映在密文中,支持并行解密 支持并行加解密运算,不须要填充
缺点 加密不支持并行运算,密文分组包含某些错误比特时会影响后续全部的分组解密 主动攻击者反转密文分组中的某些比特时会引发明文分组对应比特位的反转

在早期的TLS / SSL版本中主要使用 AES CBC 进行信息加密,后来 AES CTR 支持并行加解密的优点逐渐凸显,被TLS 1.2 及以后的版本选用,TLS / SSL 各版本支持的信息加密算法以下:
TLS信息加密算法
TLS 1.3版本加强安全性的同时对协议进行了简化,删除了对不安全加密算法的支持,对于分组密码只支持AES GCM(Galois-MAC + CTR Mode)和AES CCM(CBC-MAC + CTR Mode ),这两种加密算法实际上都是AES CTR,只是在此基础上增长了MAC(Message Authentication Code)用来验证数据完整性,这部分在下文介绍。

1.2 TLS 完整性校验与认证加密

咱们在博客:哈希算法能用来干啥?中介绍了Hash散列算法能用来进行数据完整性校验,Hash散列函数最多见的使用场合是以紧凑的方式表示并比较大量数据,主要是基于Hash函数的如下特色:

  • 能将任意长度的输入快速转化为定长输出;
  • 具有单向性,从哈希值不能反向推导出原始数据;
  • 对输入数据很是敏感,几乎没法找到两条散列相同的消息;

所以对信息数据通过Hash函数计算后的散列值可称为消息摘要(Message Digest)或消息指纹(Message Fingerprint),所使用的Hash函数也称为消息摘要函数,常见的安全Hash算法(Secure Hash Algorithms)以下:
SHA算法分类
从上图能够看出MD五、SHA-1 已经再也不安全,如今用的比较多的是SHA-25六、SHA-512等,SHA-3算法(和AES同样,也是经过全球范围内公开竞争方式实现标准化的)由于发布时间较晚,且目前 SHA-2 还没有被攻破,所以SHA-2还是主流(比特币中使用的即是SHA-256),TLS 1.2及更新的版本使用 SHA-256/384 取代了以前的MD5 / SHA-1。

使用Hash散列值能够实现数据完整性检查,可以辨别出“篡改”,但没法辨别出“假装”。假如将消息密文与对应的散列值一块儿发送,攻击者能够同时修改密文和对应的散列值,接收端仍然能经过消息完整性校验。怎么才能保证Hash散列值不被篡改呢?一个简单的思路就是对散列值进行加密后发送,使用密钥加密后的散列值称为消息认证码(Message Authentication Code)。密文与对应的MAC一块儿发送,因为攻击者不知道密钥,即使修改密文也无法生成合法的MAC,也就能保证散列值不被篡改(前提是密钥没泄露),接收方能够同时辨识出数据的“篡改”和“假装”。
MAC工做原理
消息认证码MAC有两个输入数据:消息和密钥,输入的消息能够是明文也能够是密文,输入的密钥能够是分组密码、流密码、公钥密码等,MAC算法中至少包含一种散列算法以便获取消息的散列值。根据选用的输入密钥Key类型和MAC算法,消息认证码MAC能够有不一样的实现方式,好比:

  • HMAC(Hash-MAC):使用SHA-2之类的单向Hash函数实现,根据使用散列函数的不一样可细分为HMAC-MD五、HMAC-SHA一、HMAC-SHA256/384等;
  • CMAC(CBC-MAC):使用AES之类的分组密码实现,并采用CBC模式将消息所有加密,因为CBC模式最后一个分组会受到整个消息和密钥的双重影响,所以能够将它用做MAC;
  • GMAC(Galois-MAC):使用AES之类的分组密码实现,但与CMAC不一样的是,GMAC在计算散列值时使用了Galois有限域的加法和乘法运算,能够充分利用并行处理得到更高的效率;
  • Poly1305:使用ChaCha20之类的流密码实现;

咱们先看下TLS / SSL 各版本使用了哪些数据完整性校验算法:
TLS数据完整性算法
在TLS 1.2版本以前采用HMAC-MD五、HMAC-SHA1做为数据完整性校验算法,前面已经介绍过MD5和SHA1 已经再也不安全,所以TLS 1.3 删除了对HMAC算法的支持。TLS 1.3仅支持AEAD来校验数据完整性,这个AEAD是什么呢?

**AEAD(Authenticated Encryption with Associated Data)**全称关联数据认证加密,认证加密是一种将对称密码加密和消息认证码相结合,同时知足机密性、完整性和认证功能的机制。AEAD包含对称加密和MAC计算两部分,根据两者的前后顺序能够将AEAD分为Encrypt-then-MAC、Encrypt-and-MAC、MAC-then-Encrypt 三种方法:
认证加密方法
既然AEAD是对称加密算法与MAC计算的组合,TLS 1.3 支持的AEAD算法有三种:AES-CCM、AES-GCM、ChaCha20-Poly1305。最后一种流密码认证加密算法通常须要硬件上提供一个伪随机数发生器,前两个分组密码认证加密算法使用场景比较多,举例以下:

AEAD算法 AEAD方法 优缺点对比 使用场景举例
AES-CCM
(AES-CTR + CBC-MAC)
Encrypt-and-MAC 受限于CBC模式特性,不能充分发挥并行处理的优点 TLS 1.2/1.三、IPsec、WLAN WPA二、BT LE等
AES-GCM
(AES-CTR + Galois-MAC)
Encrypt-then-MAC 能够充分利用并行处理提升效率 TLS 1.2/1.三、IPsec、WLAN WPA三、SSH等

AES-GCM认证加密算法能够充分利用并行处理提升效率,也是TLS 1.2/1.3 优先推荐的认证加密算法,下面简单介绍下GCM认证加密过程(图片取自博客:什么是 AES-GCM加密算法):
AES-GCM认证加密过程
为了更直观了解AES-GCM加密算法的效率,下面给出几种对称加密与完整性校验算法的性能对比图示(只找到以AES-128-CBC-SHA1为参考的对比图,但SHA1已再也不安全):
几种对称加密与完整性校验算法性能对比
从上面的对比图能够看出,AES-128-GCM-SHA256和AES-256-GCM-SHA384的运算效率明显高于其它对称加密与完整性校验算法,AES-GCM认证加密算法的并行处理优点仍是挺明显的,这也是TLS 1.2/1.3 优先推荐使用AES-GCM认证加密算法的缘由。

1.3 TLS 报文结构

TLS (Transport Layer Security)协议是由TLS 记录协议(TLS Record Protocol)和TLS 握手协议(TLS Handshake Protocol)这两层协议叠加而成的,位于底层的TLS 记录协议负责进行信息传输和认证加密,位于上层的TLS 握手协议则负责除加密之外的其它各类操做,好比密钥协商交换等。上层的TLS 握手协议又能够分为4个子协议,TLS 协议的层次结构以下图所示:
TLS协议的层次结构
前面已经介绍了TLS 协议的认证加密算法,这里先介绍TLS 记录协议的报文结构,每一条TLS 记录以一个短标头起始,标头包含记录内容的类型(或子协议)、协议版本和长度,消息数据紧跟在标头以后,以下图所示:
TLS记录报文
TLS记录报文的字段能够用以下数据结构定义:

enum { 
 
  
change_cipher_spec (20),
alert (21),
handshake (22),
application_data (23)
} ContentType;

struct { 
 
  
uint8 major;
uint8 minor;
} ProtocolVersion;

struct { 
 
  
ContentType type;
ProtocolVersion version;
uint16 length; /* 最大长度为2^14(16 384)字节 */
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

了解了TLS 记录报文结构,前面也介绍了认证加密过程,下面以AES-GCM为例,看看密文(消息明文AES-CNT加密而来,当不须要对消息加密时,此处保持明文便可)和MAC(将序列号、标头等附加信息与密文一块儿经过Galois-MAC计算而来)是如何添加进TLS 记录报文的:
TLS认证加密记录报文
上图中的几个字段做用以下:

  • 序列号:任一端都有自身的序列号并跟踪来自另外一端TLS记录的数量,能确保消息不被重放攻击;
  • 标头:将标头做为计算GMAC输入的一部分,能确保未进行加密的标头不会遭受篡改;
  • nonce:在加密通讯中仅使用一次的密钥,好比前面介绍过的 IV(Initialization Vector)或CTR初始值。

握手是TLS协议中最精密复杂的部分,咱们后面再介绍。回到开头介绍信息加密时对称密钥加密与非对称密钥加密的优缺点对比,对称密钥加密虽然比较高效,TLS 1.3 优先推荐的AES-GCM认证加密算法也能同时保证通讯消息的机密性、完整性、真实性,但共享密钥的交换是个问题,非对称密钥加密法正好能弥补这个不足,做为通讯双方传递共享密钥的加密算法,下面介绍TLS 的共享密钥是如何交换的。

1.4 TLS 密钥交换

早在DES对称加密法诞生前,共享密钥的交换就一直是个难题,在没有良好解决方案以前靠专人面对面传递共享密钥(还记得碟战中的密码本么)。直到1976年,共享密钥交换的难题被sun公司的高级工程师迪菲和斯坦福大学电子系教授黑尔曼两人解决,他们提出的共享密钥交换方案被命名为Diffie–Hellman key exchange,这也是非对称公私密钥加密系统诞生的基础。

Diffie–Hellman是如何实现共享密钥交换的呢?答案天然来自于数学,他们两人花了两年多时间找到了一种难以逆转的单向函数:取模运算(modular arithmetic),单向函数或不可逆函数的特色就是正向计算结果惟1、逆向运算结果不肯定(好比 11 * 9 = 8 (mod 13)正向计算结果惟一,但问你“在模等于13的体系中,什么数乘以9后余数为8?”,这个问题显然不能逆运算,因此“模运算”就是一个单向函数,前面介绍的单向散列函数内部也用到了模运算)。非对称密钥加密原理和Diffie–Hellman密钥交换原理在博文:区块链中的现代密码学中已经有过简单介绍,再将该博文中关于Diffie–Hellman密钥交换原理的介绍展现以下:
DH密钥交换过程

明白了模运算,咱们就能知道它是怎么用来传递钥匙的了,过程以下:

  1. 爱丽丝和鲍勃两我的都约定使用Gx mod P函数(G、P要求是质数,好比G = 七、P = 101);
  2. 爱丽丝随便想出一个数A(好比A = 3),鲍勃也随便想出一个数B(好比B = 6);
  3. 他们两我的分别把本身想出来的这个数,代入函数Gx mod P计算一下,好比爱丽丝算完等于α,鲍勃算完等于β;
  4. 两人把计算结果告诉对方,直接打电话也行,写信也行,反正是不怕被伊芙偷听的。缘由刚刚说过:由于伊芙偷听到的只不过是模运算的结果,而这个结果是不可逆的,因此就算伊芙知道结果,也无法倒推出以前的值;
  5. 等爱丽丝和鲍勃都获得对方的结果以后,爱丽丝再作一次βA mod P运算(也即GA·B mod P),鲍勃作一次αB mod P运算(也即GA·B mod P);
  6. 这两我的算完后,他们将获得彻底同样的结果(按上例取值的结果是45),这个相同的结果就能够看成他们的钥匙。整个过程没人传递过钥匙,但双方都拿到了一样的钥匙。对窃听者伊芙来讲,她偷听到的只是模运算的结果,由于这种运算是不可逆的,因此伊芙偷听了也白听。

从上面Diffie–Hellman密钥交换过程可知,爱丽丝与鲍勃各自生成两个参数A + α、B + β,相互发送其中一个参数(α 和 β)到对端,再通过计算,就能够获得共享密钥了。最开始两人还须要约定计算函数(Gx mod P),所以还须要两个参数 G + P(能够称为域参数,对于Web通讯常由服务器选取域参数并发送给客户端)来约定初始条件,而DH密钥交换的安全性在很大程度上也取决于这两个域参数的质量。

DH密钥交换过程当中,由服务器向客户端提供三个参数(两个域参数和一个计算结果),客户端向服务器提供一个计算结果,有些场景下两个域参数以静态方式被嵌入到服务器和客户端的证书中,这就可能致使DH密钥交换的结果是一直不变的共享密钥,就没法具有前向保密(指即使在密钥泄露的状况下,也不能拿泄露密钥解密以前截获的密文)的能力。要想具有前向保密能力,就须要每次交换的共享密钥都不同,也就要求DH密钥交换中的两个域参数每次都是临时生成且不重复的,具有这种特性的DH称为DHE (Ephemeral Diffie-Hellman),DHE也是TLS 1.2/1.3 支持的密钥交换方案。

经过DHE密钥协商方案,就能够实现对称加密中共享密钥的交换,有了共享密钥,通讯双方就可使用认证加密技术进行安全通讯了吗?假如主动攻击者在密钥交换前冒充对端,与通讯双方分别完成密钥交换,并进行正常的认证加密通讯,通讯双方多是难以察觉的,这就带来了信息泄露和被篡改的风险,这种攻击也称为中间人攻击(Man-In-The-Middle attack),MITM攻击过程图示以下:
DHE密钥协商遇中间人攻击
咱们该如何应对中间人攻击呢?最主要的就是要确认通讯对端的身份,前面介绍过的消息认证码MAC具备身份认证的功能(只能确认密钥持有者的身份),主动攻击者不知道密钥因此无法生成合法的MAC,咱们能够借鉴这种思路吗?显然是不能的,正由于没有共享密钥才须要DHE密钥协商,有了密钥天然就不须要DHE密钥协商了。

1.5 TLS 数字签名

还记得博文:区块链中的现代密码学中提到的数字签名吗?非对称密钥加密法正向使用(公钥加密 + 私钥解密)能够用来加密信息,逆向使用(私钥加密 + 公钥解密)能够做为数字签名。该特性主要得益于公私密钥对的一个性质:公钥加密的信息私钥可以解密,私钥加密的信息公钥也可以解密,公钥对外公开任何人均可以持有,私钥则只有本人持有

这就意味着任何想向私钥持有者(好比Alice)发送敏感信息的一方(好比Bob),只要获取到Alice的公钥,就可使用该公钥加密敏感信息后将密文发送给Alice,该密文只有私钥持有者Alice能解密。Alice若是想对外发布一个声明,为了防止别人以本身的名义伪造该声明,可使用本身的私钥将该声明加密后,将密文发布给目标人群,任何人均可以使用Alice的公钥来解密该声明,确认该声明确实由Alice本人发布,别人没法伪造,Alice也没法否定。非对称密钥加密法正向和逆向使用的示意图示以下:
TLS信息加密与数字签名
最先发明的非对称密钥加密法是RSA加密法,RSA的诞生也得益于Diffie、Hellman两人发表的非对称公私密钥加密系统的概念。在DH密钥交换方案发布的第二年,Ron Rivest、Adi Shamir、Leonard Adleman三人就实现了首个非对称公私密钥加密算法:RSA加密法,该加密算法的实现一样离不开不可逆的单向函数 — 模运算。

RSA加密法的实现原理已经在博文:区块链中的现代密码学中简单介绍过了,再将该博文中RSA加密法实现原理展现以下:
RSA加密法实现原理

  1. 爱丽丝展现出来的公开钥匙,是经过两个比较大的素数p和q相乘获得的一个更大的数N获得的。p和q具体是多少,爱丽丝只要本身知道就行,千万不要告诉别人,而乘积N是公开的,谁均可以知道;
  2. 凡是要给爱丽丝发消息的人,都须要用N来加密,加密的过程依然用的是模运算,并且模就是N。整个数学过程会保证这个模运算不可逆,因此伊芙就算知道N也没用;
  3. 爱丽丝解密时就不须要N了,而是要用到p和q的具体值,而这两个值别人都不知道,只有爱丽丝本身知道。具体来讲,爱丽丝私下作的另外一个模运算中的模,并非刚刚咱们说的N,而是另一个值(p-1) x (q-1),这个公式中就必需要知道p和q究竟是多少才行。至于为何是(p-1) x (q-1),数学原理会保证这样操做能算出一把新钥匙,这把新钥匙就是爱丽丝本身的私钥,用这把私钥必定能够解出原文。

从上面的过程能够看到,RSA加密法公私钥的安全性取决于P、Q的选取和保密,公钥E 和 公共模数N 是对外公开的,外界在知道N 和E 的状况下,是无法进行质因数分解反求出P 和Q 的,特别在N 比较大的状况下。也就是说,RSA加密法的安全强度是跟N 的长度直接相关的,1024位长度的N (也即RSA-1024)已经被证实不安全了,目前TLS 1.2/1.3 推荐使用N 的长度大于2048位。下面给出一份粗略对比不一样类型加密算法的安全强度位数与安全级别的列表供参考(表中数据是2012年统计的,随着计算机性能提高,攻击手段更强了,安全强度天然也要随时间提高):
密码强度推荐
前面介绍了TLS 1.2/1.3 目前推荐的对称密钥加密法安全强度为AES-128,与此安全级别差很少的RSA加密法与DHE密钥交换算法的安全强度为RSA-3248和DHE-3248,对应安全级别的单向散列函数的安全强度为SHA-256/384。上表还列举出一个椭圆曲线加密法,该算法属于哪一类呢?

椭圆曲线加密法ECC (Elliptic-Curve Cryptography)是最近备受关注的一种非对称公私密钥加密算法(能够参考博文:椭圆曲线密码算法),从上面的安全强度位数对比中能够看出:

  • ECC所需的密钥长度比RSA短不少(RSA-3248与ECC-256安全级别至关),这就减小了密钥存储和传输的要求;
  • ECC利用有限域上的椭圆曲线运算进行加解密的计算量比RSA利用指数运算进行加解密的计算量小不少,这就提升了公私钥加解密的效率,密钥越长RSA指数运算量越大,ECC带来的效率提高越明显。

所以,ECC仍是有取代RSA的潜力的,不过ECC更多的是做为一种数学运算工具来升级现有的非对称密钥加密算法,好比 ECDHE(= DHE + ECC) 就是使用ECC在有限域上的椭圆曲线运算取代DHE在有限域(Galois Field)上的指数运算,大幅缩短密钥长度并下降计算量。

反应快的朋友可能会提出一个疑问:RSA算法既然能够同时支持信息加密与数字签名,客户端直接使用服务器端提供的RSA公钥将共享密钥加密后发给服务器,服务器只有使用本身的RSA私钥才能解密,这不就能够解决对称加密中共享密钥交换的问题,并且不须要DHE密钥协商了吗?

单靠RSA加密法确实也能够实现共享密钥的交换,但RSA加密法有个缺点,因为服务器公钥更新并不方便,因此服务器公钥与私钥通常会保持多年不变,一旦RSA私钥泄露或者被破解(随着计算机性能提高,安全强度低的旧密码能够被破解),以前截获的消息就能够解密了,攻击者就能够利用这点长期记录全部加密流量,等待有朝一日得到RSA私钥后解密过去记录的全部加密信息,也就是说RSA并不支持前向保密性,也所以TLS 1.3 再也不单独使用RSA进行共享密钥交换。

TLS 1.3 支持的具备前向保密性的密钥交换方案都是“DHE + 数字签名”的组合,DHE负责密钥协商,数字签名负责验证通讯对端的身份。咱们很天然就能想到"DHE + RSA"的密钥协商和身份验证方案,这也是TLS 1.3 支持的方案之一。这套方案有改进空间吗?

前面介绍的EC (Elliptic-Curve)椭圆曲线数学工具就派上用场了,使用椭圆曲线(Elliptic-Curve)运算取代DHE中有限域(Galois Field)上的指数运算,就能够将DHE密钥协商算法的安全性提高、计算量减少,升级为ECDHE(Elliptic-Curve Diffie–Hellman Ephemeral)密钥协商方案。数字签名算法能够借助ECC实现升级吗?

RSA数字签名算法并不适合用椭圆曲线运算升级,NIST(美国国家标准技术研究所)于1991年将DSA(Digital Signature Algorithm)用于数字签名标准(DSS: Digital Signature Standard),DSA算法跟DHE采用了相似的数学工具:有限域中的离散对数概念(想了解DSA原理,可参考博文:DSA-数据签名算法),跟DHE和RSA有相近的安全强度,因为DSA是专门为数字签名设计的算法(标准DSA算法不能用于数据加密),所以在数字签名方面比RSA效率跟高一些。

因为DSA跟DHE采用了相似的数学工具,都是基于有限域中的指数运算(利用有限域中的离散对数运算很是困难的特性,来保证破解的难度),所以也可使用椭圆曲线运算取代DSA中有限域上的指数运算,将DSA数字签名算法的安全性提高、计算量减少,升级为ECDSA (Elliptic Curve Digital Signature Algorithm)。

类别 DHE RSA DSA ECC
特色 利用在有限域中求解离散对数的困难度保证安全性 利用对大数进行质因数分解的困难度保证安全性 利用在有限域中求解离散对数的困难度保证安全性 利用在椭圆曲线上求解离散对数的困难度保证安全性
优势 能够安全的进行密钥协商,支持前向保密性 既能够用于信息加密,又能够用于数字签名 进行数字签名的效率比RSA更高 有更强的安全性,更短的密钥长度,更高的计算效率
缺点 没法验证通讯对端的身份,须要配合数字签名算法使用 不支持前向保密性 不能用于信息加密,支持率不如RSA 更多的是做为一种数学工具,跟其它的公私钥加密方案配合使用
算法升级 借助ECC提供的数学工具升级为ECDHE - 借助ECC提供的数学工具升级为ECDSA -

TLS 1.2/1.3支持的密钥协商与身份验证算法以下:
TLS各版本支持的密钥协商与身份验证算法
从上图能够看出,TLS 1.3 优先推荐的密钥协商与身份验证算法是ECDHE-ECDSA,考虑到ECC普及度暂时还不如RSA,同时提供了对ECDHE-RSA、DHE-RSA的支持。
TLS各类密钥交换算法性能对比

1.6 TLS 密码套件

前面已经介绍了TLS 使用到的认证加密算法、完整性校验算法、密钥协商算法、数字签名算法等,这些算法都是要配合使用的(单独使用没法保证信息安全传输),各种算法相互组合能够造成一套套加密方案。TLS 握手阶段,服务器与客户端须要协商都使用哪些加密算法,若是逐个协商显然效率较低,TLS将可用的加密算法组合为一个个密码套件,服务器与客户端只要协商一种密码套件,就肯定了整个加密方案中用到的全部加密算法,能提升通讯效率。

TLS密码套件主要由密钥交换方法、身份验证方法、密码定义(包括对称加密算法、安全强度、认证与分组模式)以及可选的MAC或PRF算法组合而成(若是没有采用AEAD认证加密方案,则需提供MAC消息认证码,若采用AEAD则再也不须要单独指定MAC),图示以下:
TLS密码套件格式
下面给出几个密码套件示例:
密码套件组合示例
上表中的PRF(Pseudo Random Function)指的是伪随机函数,无论是对称密钥非对称密钥的生成都离不开随机数,随机数质量的好坏决定了加密法的安全强度,真正的随机数很难获取,更经常使用的是经过算法实现的伪随机数。

从TLS 1.2起,全部的算法套件都须要明确指定它们的PRF,通常伪随机函数PRF由一个密钥secret、一颗种子seed、一个惟一标签label 构成(引入种子和标签便于每次生成不一样的伪随机数,而密钥secret能够重用)。PRF的生成主要使用了Hash算法,因此密码套件中的PRF字段是以散列函数强度来描述的(好比SHA-256),PRF的计算过程简单展现以下:

P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
					   HMAC_hash(secret, A(2) + seed) +
					   HMAC_hash(secret, A(3) + seed) + ...
// A(i) 函数定义以下:
A(1) = HMAC_hash(secret, seed)
A(2) = HMAC_hash(secret, A(1))
...
A(i) = HMAC_hash(secret, A(i-1))

// PRF则是结合标签和种子对 P_hash 的封装:
PRF(secret, label, seed) = P_hash(secret, label + seed)

1.7 TLS 网络攻防

技术是在解决问题的过程当中进步的,网络安全也是在网络攻击中逐渐提升的,前面介绍的每种加密方案都是为了解决当前加密方案遇到的问题而诞生的,好比MAC是为解决消息可能被篡改或伪造的问题产生的、DHE是为了解决共享密钥交换问题发明的、DSA是为了解决通讯对端可能假装身份的问题产生的。

咱们已经介绍了TLS 加密方案中用到的全部加密算法,这套加密方案能挡住几乎全部的网络攻击吗?咱们来回顾下整个信息安全传输流程:

  1. 服务器与客户端分别获取对方的公钥;
  2. 服务器与客户端之间经过密钥协商算法(好比ECDHE)进行共享密钥的协商,首先由服务器选取域参数肯定双方的计算函数,包括服务器生成的一个随机数,一块儿使用本身的私钥对其进行数字签名(好比ECDSA / RSA)后发送给客户端;
  3. 客户端收到服务器发来的消息,使用服务器公钥验证经过后保存备用,本身再生成一个随机数使用本身的私钥对其进行数字签名后发送给服务器,服务器与客户端经过ECDHE密钥协商算法就能够计算出双方后续使用的共享密钥;
  4. 服务器与客户端之间使用协商好的共享密钥,对后续的消息进行认证加密(好比AES-GCM),只要共享密钥不泄露,攻击者很难解密出传输的消息明文。

看起来整个过程挺安全,密钥协商过程解决了共享密钥交换的问题,数字签名能够确认通讯对端的身份,认证加密算法能够保证通讯内容的机密性、完整性、真实性,看似无懈可击时回到起点,审视下初始条件或假设。这里的初始条件是咱们已经得到了通讯对端的公钥,但这个公钥确实是通讯对端的吗?攻击者可让你得到的是他伪造的公钥吗?
ECDHE数字签名遇中间人攻击
还拿中间人攻击举例,当客户端与服务器互相发送公钥C 和公钥S 时,攻击者截获这两个公钥,本身再生成两对儿公私钥A和B,分别冒充客户端和服务器的通讯对端分别与他们交换公钥、协商共享密钥、认证加密通讯,这样攻击者就能够获知共享密钥解密后续全部的消息。这又回到了前面介绍DHE密钥协商时遇到的攻击者假装成通讯对端的问题,数字签名确认通讯对端身份的做用没有发挥出来,问题出在哪呢?

再回顾整个过程不难发现,问题就出在公钥的交换上,咱们没法确认咱们得到的公钥确实是通讯对端的公钥,这也是数字签名没法解决的问题。也就说是,要正确使用数字签名,前提就是用于验证签名的公钥必须属于真正的通讯对端。该如何确认本身获得的公钥是合法的呢?

公钥不怕泄露,惟一担忧的就是被篡改伪造。生活中咱们想判断一则消息是否真实可信,经常会看是否有权威机构或我的为其背书,咱们想确认本身获得的公钥是否真实合法,也能够引入权威第三方对其签名,通过可信第三方签名的公钥能够称为证书。客户端与服务器在交换公钥阶段,改成交换由可信第三方签名的证书,就能保证本身得到的公钥是真实可信的吗?

假如攻击者也得到了一个由可信第三方签名的证书,岂不是像前面直接交换公钥遇到的问题同样。很显然,证书里面不止包含通讯对端的公钥,还应有身份标识信息。证书系统是如何工做的?TLS 握手协议都作了哪些工做?咱们在下一篇博客:TLS 1.2/1.3 握手协议与性能优化中介绍。

更多文章: