HTTPS 深度理解 篇上

首先,先来看看一些理论知识。

  • 对称加密
  • 非对称加密
  • 单项散列函数
  • 消息认证码
  • 数字签名
  • 伪随机数生成器

加密技术

1. 对称加密

对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。对称加密只有一个秘钥,作为私钥。

常见的对称加密算法:DES,AES,3DES

2. 非对称加密

非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密。

常见的非对称加密算法:RSA,ECC(圆锥曲线密码学)

3. 区别

对称加密算法相比非对称加密算法来说,加解密的效率要高得多。但是缺陷在于对于秘钥的管理上,以及在非安全信道中通讯时,密钥交换的安全性不能保障。所以在实际的网络环境中,会将两者混合使用。

密匙配送问题?

需要明确的是,对称加密是否安全取决于密匙是否泄露,因此我们需要解决对密匙进行保密,在密匙配送过程中需要保障私密性。主要有一下几种方式:

  1. 通过事先共享密钥来解决
  2. 通过密钥分配中心来解决
  3. 通过Diffie-Hellman密钥交换来解决
  4. 通过公钥密码来解决

事先密钥共享

事先共享密钥尽管有效,但却有一定的局限性。首先,要想事先共享密钥,就需要用一种安全的方式将密钥交给对方。如果是公司里坐在你旁边的同事,要事先共享密钥可能非常容易,只要将密钥保存在存储卡中交给他就可以了。然而,要将密钥安全地交给一个前几天刚刚在网上认识的朋友就非常困难。如果用邮件等方式发送,则密钥可能会被窃听。另外邮寄存储卡也不安全,因为在邮寄的途中可能会被别人窃取。

此外,即便能够实现事先共享密钥,但在人数很多的情况下,通信所需要的密钥数量也会增大,这就产生了问题。例如,一个公司中的1000名员工需要彼此进行加密通信。假设1000名员工中每一名员工都可以和除自己之外的999名员工进行通信,则每个人就需要999个通信密钥,也就是说,整个公司所需要的密钥数量为:

1000 x 999 / 2= 499500

全公司需要生成49万9500个密钥,这实在是不现实。因此,事先共享密钥尽管有效,但依然有一定的局限性。

通过密钥分配中心

如果所有参与加密通信的人都需要事先共享密钥,则密钥的数量会变得巨大,在这样的情况下,我们可以使用密钥分配中心(Key Distribution Center,KDC)来解决密钥配送问题。当需要进行加密通信时,密钥分配中心会随机生成一个通信密钥,每个人只要和密钥分配中心事先共享密钥就可以了。

存在的问题有:

  1. 密匙分配中心如果单点故障,会导致所有的认证操作瘫痪
  2. 如果黑客入侵了密钥分配中心,所有的加密操作都会被破译

Diffie-Hellman

使用RSA密钥协商算法传输会话密钥的时候,会话密钥完全由客户端控制,并没有服务器的参与,所以叫作密钥传输。而DH算法确切地说,实现的是密钥交换或者密钥协商,DH算法在进行密钥协商的时候,通信双方的任何一方无法独自计算出一个会话密钥,通信双方各自保留一部分关键信息,再将另外一部分信息告诉对方,双方有了全部信息才能共同计算出相同的会话密钥。

DH 算法分为两种:动态DH和静态DH。静态DH算法中每次通信时使用的加密算法参数固定,优点是避免频繁生成参数,消耗性能,缺点是无法保障私钥泄露后所有历史会话信息被破解。动态DH算法在每次通信时动态生成加密算法参数,私钥保存在内存中。

通过公钥的方式

在对称加密中,加密密钥和解密密钥是相同的,但非对称加密中,加密密钥和解密密钥却是不同的。只要拥有加密密钥,任何人都可以进行加密,但没有解密密钥是无法解密的。因此,非对称加密的一个重要性质,就是只有拥有解密密钥的人才能够进行解密。

混合加密

混合密码系统是将对称密码和公钥密码的优势相结合的方法。混合密码系统中会先用快速的对称密码来对消息进行加密,这样消息就被转换为了密文,从而也就保证了消息的机密性。然后我们只要保证对称密码的密钥的机密性就可以了。这里就轮到公钥密码出场了,我们可以用公钥密码对加密消息时使用的对称密码的密钥进行加密。由于对称密码的密钥一般比消息本身要短,因此公钥密码速度慢的问题就可以忽略了。

将消息通过对称密码来加密,将加密消息时使用的密钥通过公钥密码来加密,这样的两步密码机制就是混合密码系统的本质。

总结出混合加密的特点:

  1. 用对称密码加密消息
  2. 通过伪随机数生成器生成对称密码加密中使用的会话密钥
  3. 用公钥密码加密会话密钥
  4. 从混合密码系统外部赋予公钥密码加密时使用的密钥

加密过程:

解密过程:

认证技术

单项散列函数

单向散列函数有一个输入和一个输出,其中输人称为消息,输出称为散列值。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。

性质:

  1. 根据任意长度的消息计算出固定长度的散列值
  2. 能够快速计算出散列值
  3. 消息不同散列值也不同
  4. 具备单向性

实际用途:

  1. 检测文件是否被篡改
  2. 基于口令的加密
  3. 消息认证码
  4. 数字签名
  5. 伪随机数生成器
  6. 一次性口令

常见的单项散列函数有:MD5,SHA-1,SHA-2,SHA-3。

重要特点:能辨别篡改,但是无法辨别伪装。

消息认证码

消息认证吗是一种确认完整性并进行认证的技术。使用消息认证码可以确认自己收到的消息是否就是发送者的本意,也就是说,使用消息认证码可以判断消息是否被篡改,以及是否有人伪装成发送者发送了该消息。

消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为MAC值。要计算MAC值必须要持有共享密钥,消息认证码是一种与密钥相关联的单向散列函数

消息认证码的实现方式:

  1. 使用单项散列函数:HMAC..
  2. 使用分组密码实现

对消息认证码进行攻击:

  1. 重放攻击:解决办法有,为消息编号、为消息添加时间戳、在通信之前接收方向发送方发送 nonce
  2. 密钥推测攻击

消息认证码无法解决防止否认的问题。消息接收方 B 无法向第三方证明消息是消息发送方 A 发送的。因为 A 和 B 共享同一个密钥,第三方无法确定消息是 A 发送的还是 B 发送的。如果说消息是 A 发送的,但是 A 又进行了否认,就出现了 “扯皮现象”。只要通信双方无法确定对方身份那么就会出现抵赖现象,可以用数字签名技术防止抵赖。

数字签名

在数字签名技术中,出现了下面两种行为:

  1. 生成消息签名的行为
  2. 验证消息签名的行为

通过签名密钥来对消息进行签名,通过验证密钥来对消息进行校验。十分类似于非对称加密过程,非对称机密过程就是使用公钥进行解密,私钥进行加密。可以将签名密钥类比于私钥,将验证密钥类比于公钥。

流程

结合这前面提到的单向散列函数,我们可以整理出数字签名中生成签名和验证签名的流程图:

Snipaste_2021-10-01_16-14-02.jpg
Snipaste_2021-10-01_16-14-02.jpg

看完上面这张图你可能会有疑问。

为什么要对使用单项散列函数对消息计算散列值之后,用私钥对散列值进行签名,而不直接用私钥进行签名?原因是直接对消息进行签名需要对整个消息进行加密,耗时长。使用单向散列函数可以在保留消息特征值的情况下将消息转换为固定长度。

常用的数字签名算法:RSA数字签名算法,DSA数字签名算法,ECDSA数字签名算法

数字签名的疑问

数字签名能够保障机密性吗?

答案是否定的,数字签名不能保障机密性,如果要保障机密性需要密码和签名结合。

数字签名被拷贝了还能保障安全性吗?

数字签名存在的原因是确定消息发送者和数字签名签发者是同一人,特定的签名者和特定的消息绑定在了一起。无论将签名复制多少份,“是谁对这条消息进行了签名”这一事实是不会发生任何改变的。总之,签名可以被复制,但这并不代表签名会失去意义。

数字签名能够保障消息不被篡改吗?

数字签名能够识别消息是否被篡改,但是无法防止消息被篡改。而且因为单项散列函数的性质,你几乎不可能在通过同时修改证书和消息来使得消息签名成功。

对数字签名的攻击

  1. 中间人攻击:是指同时同时拦截消息发送双方的消息,进行伪装。如何防止中间人攻击?需要确定自己得到的公钥是否真的属于自己通信的对象。一般来说可以通过公钥的证书来确定,自己预先保留一份公钥的证书,用这个证书来确定公钥所属的对象。
  2. 对单向散列函数进行攻击
  3. 利用数字签名攻击公钥密码

数字签名无法解决的问题

如果验证签名的公钥是中间人伪造的,数字证书就会完全失效。

证书

证书包含两个内容:发送方公钥+可信机构数字签名。可信机构也称为认证机构。

Snipaste_2021-10-01_16-45-45.jpg
Snipaste_2021-10-01_16-45-45.jpg

公钥基础设施

公钥基础设施PKI,是为了更有效的利用公钥而制定的一些列规范和规格的总称。常用的标准是 X.509 标准。

包含几个名词:用户、认证机构(CA)、仓库(存储证书的数据库)

证书链:获得证书的组织利用自己的公钥进行数字签名的行为叫做自签名。

对证书的攻击

在公钥注册时之前进行攻击

证书是认证机构对公钥及其持有者的信息加上数字签名的产物,由于加上数字签名之后会非常难以攻击,因此我们可以考虑对施加数字签名之前的公钥进行攻击。防止方式有两种

  1. 使用认证机构的公钥对自己的公钥进行加密,攻击者即使拿到被加密的报文,也无法解密,也就无法得到待签名的公钥,也就不能伪造身份
  2. 认证机构在进行签名时可以再次向请求签发者确认公钥内容

注册相似的人名进行攻击

要防止这种攻击,认证机构必须确认证书中所包含的信息是否真的是其持有者的个人信息,当本人身份确认失败时则不向其颁发证书。

窃取认证机构的私钥

这种实在是没辙,只能事后补救

攻击者伪装成认证机构进行攻击

消息接收方需要自行判定认证机构是否可信

钻 CRL(作废证书)的空子进行攻击

  1. 利用 CRL 发布的时间差来进行攻击
  2. 通过 CRL 时间差实现否认

TLS/SSL协议

TLS协议是SSL 协议的升级版,两者没有本质区别。

可以使用TLS/SSL协议解决任何基于TCP/IP的网络应用,都会遇到安全问题,比如遇到中间人攻击、无法对对端进行身份验证、传输的数据不具备机密性等问题。

TLS/SSL协议位于应用层协议和TCP之间,构建在TCP之上,由TCP协议保证数据传输的可靠性,任何数据到达TCP之前,都经过TLS/SSL协议处理。对于应用层协议来说,它无须过多改变,引入TLS/SSL协议即可保证数据机密性和完整性。任何应用层协议(HTTP、SMTP、FTP、其他自定义应用层协议)都可以结合TLS/SSL协议。

OpenSSL 和 TLS/SSL 的关系:TLS/SSL协议是设计规范,有很多实现方式,包括 JDK实现,OpenSSL实现。OpenSSL是一个底层密码库,封装了所有的密码学算法、证书管理、TLS/SSL协议实现。

HTTPS和TLS/SSL的关系:HTTP和TLS/SSL协议组合在一起就是HTTPS, HTTPS等同于HTTP+TLS/SSL,就是说HTTPS拥有HTTP所有的特征,并且HTTP消息由TLS/SSL协议进行安全保护。

TLS/SSL协议包含三大步骤:认证、密钥协商、数据加密。

加密算法与MAC算法

MAC 值 = (单向散列函数,共享密钥)

为了对数据进行加密,可以采用对称加密算法或者非对称加密算法,有加密算法必定就有MAC算法,两者是一个整体。

可以使用 RSA 加密(非对称加密)算法来进行通信,只要通信双方持有对方公钥就行。但是效率十分低。那么就必须要结合使用对称加密算法,既然要使用对称加密算法,那么就需要规定如何协商共享密钥,引出了密钥协商算法。

密钥协商算法

常用的两种密钥协商算法:RSA密钥协商算法,DH密钥协商算法。

RSA密钥协商算法

  1. 客户端向服务器端发起连接请求,服务器端发送RSA密钥对的公钥给客户端。
  2. 客户端通过随机数生成器生成一个预备主密钥,用服务器的公钥加密并发送给服务器端。
  3. 服务器解密预备主密钥,假如能够正确解密,则说明客户端和服务器端共同协商出一个预备主密钥。

DH密钥协商算法

DH算法最大的优点就在于预备主密钥是客户端和服务器端共同计算出来的,只有经过消息互换才能计算出预备主密钥,大概的流程如下:

  1. 客户端向服务器端发起连接请求。
  2. 服务器端生成一个RSA密钥对,并将公钥发送给客户端。
  3. 服务器端生成DH参数和服务器DH密钥对,用RSA私钥签名DH参数和服务器DH公钥,最后将签名值、DH参数、服务器DH公钥发送给客户端。
  4. 客户端通过服务器RSA的公钥验证签名,获取到DH参数和服务器DH公钥。
  5. 客户端通过DH参数生成客户端的DH密钥对,并将客户端DH公钥发送给服务器端。
  6. 客户端通过客户端DH私钥和服务器端DH公钥计算出预备主密钥。
  7. 服务器端接收到客户端的DH公钥,结合服务器的DH私钥计算出预备主密钥。
  8. 最终客户端和服务器端计算出的预备主密钥能够保持一致。

在发送公钥时,服务器会对公钥进行签名,确保公钥没有被伪造或者篡改

什么是 HTTPS

HTTPS 加密详解

架构

HTTPS中加密层和握手层的关系:

握手层在加密层的上层,握手层提供加密层所需要的信息(密钥块),对于一个HTTPS请求来说,HTTP消息在没有完成握手之前,是不会传递给加密层的,一旦握手层处理完毕,最终应用层所有的HTTP消息交由加密层进行加密。

使用 RSA 密码套件:

使用 DH 密码套件:

1、握手

1)认证

客户端在进行密钥交换之前,必须认证服务器的身份,否则就会存在中间人攻击,而服务器实体并不能自己证明自己,所以需要通过CA机构来进行认证,认证的技术解决方案就是签名的数字证书。证书中会说明CA机构采用的数字签名算法,客户端获取到证书后,会采用相应的签名算法进行验证,一旦验证通过,则表示客户端成功认证了服务器端的身份。

2)密码套件协商

密码套件决定了本次连接客户端和服务器端采用的加密算法、HMAC算法、密钥协商算法等各类算法。密码套件包含以下内容:

  1. 身份验证算法。
  2. 密码协商算法。
  3. 加密算法或者加密模式。
  4. HMAC算法的加密基元。
  5. 伪随机函数算法(PRF)的加密基元,需要注意的是,不同的TLS/SSL协议版本、密码套件,PRF算法最终使用的加密基元和HMAC算法使用的加密基元是不一样的。

3)密钥协商

密码套件会决定客户端和服务器端使用何种算法进行密钥协商。为了保持前向安全性,目前使用最多的密钥协商算法就是DHE算法和ECDHE算法,这两个算法和服务器的密钥对关系不大,也就是说密钥的协商不取决于服务器的密钥对,所以服务器的私钥即使泄露,也不会造成太大的安全风险。

4)握手消息完整性校验

这一步的目的是防止握手过程中的消息被篡改,如果发生篡改,校验会失败。校验过程如下:

  1. 客户端将发送和接收到的所有握手消息组合在一起,然后计算出摘要数据,握手层使用密钥块对摘要数据进行加密和完整性保护,然后发送给服务器
  2. 服务器接收到验证消息后,使用加密块解密出摘要数据
  3. 紧接着服务器自行计算发送和接收的所有握手消息,再计算出消息的摘要数据,如果摘要数据和解密出的摘要数据相同,代表客户端发送的消息没有被篡改

2、加密

通过握手之后,通信双方协商出了共享密钥,就可以结合密码套件中指定的加密算法进行机密通信了。

常见的几种加密算法有:

  1. 流密码加密模式:在进行加密之前,先计算HMAC值,然后对输入值和HMAC值进行加密,也就是采用MAC-then-Encrypt的加密模式,加密和完整性处理是独立运行的。(不安全,不推荐使用)
  2. 分组加密模式:加密和完整性处理是分开处理的
  3. AEAD模式:一步就能解决加密和完整性处理