TLS 的目的便是解决数据的
一、Record 记录协议 (对称加解密)
二、HandShake 握手,挥手
验证通讯双方身份
交换加解密的安全套件
协商加密解密参数
对称加密
其实不管什么握手最终都要做的都是将对称加密密钥传递给通讯的双方,这样才能实现加解密。
对称加密就是利用同一把钥匙对一串明文进行加密和解密。
常见的对称加密方式分为两大类
- 流式加密算法 :
RC4
,ChaCha20-Poly1305
- 分组加密算法 :
AES-CBC
,AES-GCM
RC4由于存在严重安全漏洞,已经基本不再使用;AES-CBC容易遭受BEAST和LUCKY13攻击,使用也逐渐减少,AES-GCM是它们的安全替代,AES-GCM也是目前最为流行的对称加密算法,其可以利用多核CPU进行高效的加解密操作。
而ChaCha20-Poly1305 也非常值得关注,Google Chrome 曾经把ChaCha20作为默认的对称加密算法,其在手机端的使用和AES-GCM 相比效果显著,其特性就表示了其省电,速度快的特性,但是目前硬件场上都对AES-GCM 有物理外挂的加持,如 AES-NI(Advanced Encryption Standard New Instruction)
。AES-NI是Intel和AMD微处理器上x86架构的一个扩展,可以从硬件上加速AES的性能,目前在服务器和PC端,CPU对AES-NI的支持率已经非常普及。不仅是AES加速,还有针对GCM的Intel的Climul指令。这些硬件外挂使得ASE-GCM的性能大幅提高,ChaCha20完败。
对称/分组密码 一般分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。对于流加密,需要将分组密码转化为流模式工作。对于块加密(或称分组加密),如果要加密超过块大小的数据,就需要涉及填充和链加密模式。
AES 最容易理解的对称加密
这里以AES算法来带入对称加密。AES 高级加密标准(Advanced Encryption Standard,AES)是美国联邦政府采用的一种区块加密标准。
其中 AES_128_GCM 就是对称加密算法
常用填充算法 PKCS7
常用分组模式 GCM
- 初级对称的加密
对称加密是利用相同的密钥进行加解密,也就是说加密和解密都是用的同一把密钥。而其原理就是简单的异或
操作。
举个简单的例子,(异或操作可理解为不进位加法)原始明文 010101 密钥 000111 ,明文 与 密钥进行异或操作。 得到加密后的密文010010 ,再用相同的密钥 000111 解密,其实又可以得到 010101 。
- 对称填充 padding
那密钥只有6位(现实一般是128,256位),要加密的明文却有可能很长很长。那么如何实现加密,上面提到了,AES是分组加密。Block cipher 分组加密
需要将待加密的数据分成块(16字节 4x4 矩阵),然后加密。最后一个块有可能不够一个完整的块(16字节),这时就需要填充。
填充方法:
- 位填充
以bit位为单位来填充。(不常用)
- 字节填充
1、补零: ...|DD DD DD DD DD DD DD DD|DD DD DD DD 00 00 00 00
|
后面补零就是了
2、ANSI X9.23: ...|DD DD DD DD DD DD DD DD| DD DD DD DD 00 00 00 04
|
后面补了几个0 在最后一位指明填了几个0 ,如上面的4个0
3、 ISO 10126: ...|DD DD DD DD DD DD DD DD| DD DD DD DD 81 A6 23 04
|
后面随便填,但是最后一个字节需要指明填了几个字节
4、PKCS7: ...|DD DD DD DD DD DD DD DD| DD DD DD DD 04 04 04 04
|
这种填充方式也是AES使用的,就是最后填充几个字节,所有的填充位就
都写上填了几个字节,如上面的4个04
- 分组工作模式 block cipher mode of operation
分组了就可以直接异或了吗?当然错误。因为单纯的异或操作无法对数据的特征进行加密。
当然单纯的分组完了就异或也有,这就是 ECB(Electronic codebook)模式
加密方式:
加密前的明文为 图1,ECB加密的方式就是 图2,可以看出,十分明显的数据特征,而我们更希望的是图3。
2、CBC (Cipher-blocking chaning)模式
这种加密的特点是,第一组明文,经过加密后的密文,会在下一组加密时先和明文进行一次异或操作,然后再和密钥进行加密,循环往复。这样就可以做到消除数据特征。
缺点:1、加密过程串行化,没有完成第一步就没法进行下一步。所以没有办法利用到多核CPU。
2、这个流程没有hash编码,这也是不安全的。
3、
CTR (Counter) 模式
通过引入一个计数器Counter 和一个初始值 Nonce 。这样相当于为每一组引入了一个干扰值,这个值先和密钥进行块加密算法,得到的结果再和明文做异或操作,这样就可以对多个块进行同时的加密。
优点:可以利用多核CPU进行加密,可并发处理。
缺点:不能提供密文消息的完整性校验。(可能会被篡改)
4、
GCM 模式
为了解决密文消息完整性校验,引入了散列函数。验证完整性:MAC(Message Authentication Code)
引入完整性校验的目的是防止密文被修改,因为传统的hash,中间人可以即乱改密文,再对改变后的密文做hash,可见单向的hash函数不能解决完整性校验。所以这里将密钥也加入hash函数中,中间人就算篡改了原密文,但是没有密钥,它无法提供篡改后的MAC值。
将加密后的密文与密钥一起放入散列函数运算,得到一个hash值,等到传输到对端后,将密钥和密文再经过该散列函数运算,再次得到一个hash值。比较是否相等,相等就表示消息是完整的。
GCM 就是 CTR + GMAC
GMAC (Galois message authentication code mode,伽罗华消息验证码)
GCM 利用GMAC(基于伽罗华域的MAC)和AES的CTR模式的组合。GMAC 比 普通的MAC 算法快。且Intel专门推出了Clmul指令用于GCM运算速度。
GCM可以提供对加密消息的完整性校验,而且还提供附加消息的完整性验证,附加消息可以是源IP,源端口之类的。下图得EK表示对称密钥k,对输入做AES运算。最后接收者会接收到密文、IV(计数器CTR的初始值)、MAC值。
- 加密完整步骤
有了填充,分组,那就完了吗??没有,生产环境中的AES加密更为复杂,这里还涉及到密钥扩展,加密轮等。
AES分组的长度是 16字节 (4x4 块)
AES | 密钥长度 (4 字节) | 分组长度 | 加密轮 |
---|---|---|---|
AES-128 | 4 (16字节) | 4 | 10 |
AES-192 | 6 (24字节) | 4 | 12 |
AES-256 | 8 (32字节) | 4 | 14 |
AES 加密流程
在完成了分组,填充后就到了真正的加密流程。
上面提到了 AES-128 是10轮,第1轮为初始论,第2-9为普通轮,第10轮为最终轮。
-
AddRoundKey 轮密钥加
矩阵中的每一个字节都与该次回合金钥(round key)做XOR异或运算;每个子密钥由密钥扩展算法产生。
在每次的加密循环中,都会由主密钥产生一把回合密钥(通过AES密钥扩展算法),这把密钥大小会跟原矩阵一样,以与原矩阵中每个对应的字节作异或(⊕)加法。
这里的回合金钥是 对原始密钥做密钥扩展算法。且每轮的做完密钥扩展算法的钥匙都不同。
-
SubBytes 字节替代
矩阵中的各字节通过一个8位的S-box进行转换,透过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。提供非线性变换能力,避免简单代数性质的攻击.
-
ShiftRows 行移位
就是简单的位移,第一行不变,第二行循环左移一位,第三行循环左移两位,第四行循环左移三位。
-
MixColumns 列混合
将矩阵的某一列与一个新矩阵做矩阵相乘。
如此便完成了加密流程。