整理TLS(SSL)协议关键步骤(下)

接着上一篇,在通信双方建立连接时,完成**协商,协商出预备主**,预备主**通过密码衍生算法算出主**,主**也叫做密码套件,从密码套件中再转换出各个**块,这些**块就是各种算法,如对称加密的**,消息验证码的**等。好了,在建立连接阶段完成协商**和决定密码套件后,接下来到了通信数据加密部分,对称加密和公开**。

 

对称加密

对称加密就是使用一个**和一个算法,将明文信息加密成密文,对称加密算法是可逆的,分为流密码和块密码两种,下面大致总结一下这两种加密方式。

流密码

一次性密码本

流密码的原理就是一次性密码本,一次性密码本的加密解密过程使用“异或”运算,使用与明文长度一致的序列进行异或运算,加密出密文,密文使用相同的序列也进行异或运算,解出明文,举个例子:

00100110 11110110 11110110 11100110

使用的加***是:

10011110 10100110 11010110 11001110

那么明文与**进行加密异或运算,得到的密文就是:

10111000 01010000 00100000 00101000

之后密文通过同样的**进行异或运算,即可解密出明文:

10111000 01010000 00100000 00101000

10011110 10100110 11010110 11001110

00100110 11110110 11110110 11100110

为了保证安全性,每次加密使用的序列都必须不同。流密码算法就是以一次性密码本为雏形实现的加密算法,也是使用异或运算,内部使用随机数生成器每次生成不同的**,保证每次加密解密得到的明文密文不同,以此保证安全性,也就是说,**是一次性的。流密码算法的优点在于速度快,可以并行处理连续的序列。

块密码

流密码是对连续的序列进行处理,块密码则是把明文序列分割成一块一块数据块,依次对每个数据块进行加密解密,最终把所有数据块合并在一起,得到完整的密文或者明文。数据块的长度称为分组长度,如果在切割数据块的时候,最后不能等分每一块数据块,则要对数据块进行填充处理,以便让数据块分组长度和**长度达到一致。块密码算法有不同的迭代方式,你可能会想,为什么要迭代?使用相同的**对每一个数据块进行加密操作不就可以了吗?迭代是为了安全性问题,来看看他们的迭代方式。

ECB电码本

ECB电码本方式就是单纯对每一个数据块使用相同的**进行加密,最后依次把所有密文数据块组合在一起,得到完整密文。

整理TLS(SSL)协议关键步骤(下)

如图所示,ECB电码本方式每一个数据块都使用相同的**进行加密解密,每个数据块之间都是互相独立没有联系的,因此操作过程也可以并行处理,这是优点,但是ECB电码本方式有一个致命的缺点,就是安全性问题,由于使用相同的**对多个数据分组进行加,假设明文序列中出现多个字符‘a’,即使它们出现在不同的分组中,被加密出来的密文是一致的,别人很容易从中观察出有多个相同的密文,得知是使用的ECB电码本方式加密。

CBC密文分组连接模式

CBC密文分组连接方式解决了EBC电码本方式的安全问题,让多个分组数据块之间建立起某种联系,它是怎么做的?来看下加密过程:

整理TLS(SSL)协议关键步骤(下)

  1. 第一步同样将明文序列等分成多块数据块,最后长度不足的进行填充。
  2. 首先处理第一块数据块,使用随机数生成器生成一个IV向量,将它和第一块数据块进行异或运算,得到的序列再和**进行加密运算得到第一块密文数据块。
  3. 然后处理第二块,对第二块明文数据块,首先和前一块密文数据块(也就是第一块)进行异或运算,然后再和**进行加密运算,得到第二块密文数据块。
  4. 接下来的操作一样,第n块明文数据块首先和第n-1块密文数据块进行异或运算,然后再和**进行运算得到第n块密文。
  5. 最后,将所有的密文数据块依次整合到一起,得到完整的密文。

从上面的步骤可以看到,CBC密文分组连接模式,在每一块加密数据块之间建立了联系,第n块数据块加密时用到的初始化向量就是第n-1块的密文数据块,第一块数据块的初始化向量IV每一次都不同。由于每块分组数据块之间有联系,在对第n块数据块进行加密前,必须得到第n-1块密文数据块,第n块数据块加密未完成,无法对第n+1块数据块进行加密操作,所以无法进行并行处理,速度较ECB电码本方式要慢,不过,加密算法重视的还是安全性问题。

CTR计数器模式

CTR计数器模式较复杂,它对每个数据块都使用不同的**进行加密,但是每个分组数据块使用的**之间是有联系的。最简单的例子就是**流之间是递增的方式。

整理TLS(SSL)协议关键步骤(下)

  1. 首先将明文等分成多个分组数据块,然后生成所有的**流,假设有n个数据块,就生成n个**流。
  2. 第一个**流生成完成后,加1得到第二个**流,第二个**流加1得到第三个**流,依次得到所有的**流。
  3. 然后开始对每一块明文数据块进行加密处理,加密使用**加**流一起运算,得到的摘要值再和明文进行异或运算得到密文。

 

消息验证码MAC

**协商,数据加密完后,到了消息验证。既然对数据进行了加密,能够保证信息安全不泄露,为什么还要消息验证呢?消息验证的作用是确认消息是完整的原始消息,中途没有被篡改过。拿对称加密举例,如果不进行消息验证,会出现什么问题?对称加密通常情况下使用通信双方共同一个**一个算法完成加密解密,任意一方只要接收到消息后,解密出可读的,意义明确的明文,就会认为这是发送方发来的原始信息。但是如果**泄露了,中间方截获了密文,使用**解密后篡改明文,再进行加密,发送到接收方手中,一样可以解出可读的消息,不会出现符号乱码,所以出现的问题就是,接收方如何确认自己收到的消息就是发送方发来的原始消息呢?

使用消息验证码进行消息验证的步骤大致如下:

整理TLS(SSL)协议关键步骤(下)

  1. 通信双方事先共享同一个**。
  2. 发送方将原始消息使用**进行MAC运算,得到消息的MAC值,将MAC值和原始消息一起发送给接收方。
  3. 接收方接收到消息后,先将消息部分与自己的**进行MAC运算,得到MAC值,再把MAC值与一同发来的MAC值进行比较,如果一致,表示消息没有被篡改,是原始消息,因为MAC值是对原始消息进行的MAC运算,只要消息发生一点变化,计算出来的MAC值都会不同。

 

数字签名-身份验证

消息验证码完成对消息的确认,确认消息是没有经过篡改的原始消息,最后,来到身份验证。没错,对消息要验证,对通信双方的身份也要进行验证,你可能会想,为什么?不是只有通信双方才有通信使用的**吗?不对,我们的通信不一定都是两人双方通信,可能是一组人一群人的通信,这样拥有**的人就有很多了,如果通信时不进行身份验证,会出现什么样的问题?

首先是消息篡改,假设A,B,C三人共同拥有通信的**,A向B发送了一条消息,被C截获了,由于C也有**,C可以解出明文,然后对其进行修改,再加密发送给B,B只要解出意义明确,可读的消息,就会认为是A发来的。第二个问题是不可抵赖性问题,同样是A,B,C三人,C给B发送了消息,但是C可以抵赖说自己没发送过,原因是A也有共同的**,A也可以发送消息给B。类似的还有,假设C发送了消息给B,但B无法向其他人证明这是C发送的,原因是A也可以使用相同的**和B进行通信,B无法向其他人证明这条消息的发送方。

出现上述问题的原因都是因为无法确定发送方身份的问题,所以除了消息验证外,身份验证也是必要的,进行身份验证,可以使用数字签名。身份验证要做到不可抵赖,关键是要找到一个可以唯一标识通信方身份的东西,就像我们每个人的指纹,身份证号码等,只能唯一标识我们自己,无法抵赖。

拿公开**RSA举例,**协商完成后,客户端拥有服务器端发来的公钥(通信加密用),自己的客户端私钥(解密服务器端发来的消息用),服务器端同理,那么对于通信双方来说,自己的私钥就是可以唯一标识自己身份的东西。对于客户端来说,私钥只有它自己拥有,在发送信息时,用自己的私钥对该信息进行“签名”,发送到服务器端处,由于服务器端有客户端公钥,可以解出签名信息,服务器端也一样,使用只有自己拥有私钥进行“签名”,无法抵赖。

生成签名:

整理TLS(SSL)协议关键步骤(下)

首先对消息进行Hash运算得出一个摘要值,然后发送方使用自己的私钥对摘要值进行签名,得到的签名值和消息一起发送给接收方。

整理TLS(SSL)协议关键步骤(下)

接收方接收到信息后,首先对签名值进行运算得出一个签名值(其使用摘要值好一点),然后对消息进行Hash运算得到摘要值,然后比较这两个摘要值是否一致,如一致就能确认发送方的身份。