本帖最后由 DKENNY 于 2024-10-24 17:26 编辑
#申请原创# @21小跑堂
前言 我们很多人对加密算法这一块都不是太过于了解。就像我们这一次介绍的AES算法,这到底是个什么玩意儿呢?其实,AES算法是一种典型的对称加密算法。
Q. 什么是AES 算法? 那么,这个对称加密算法又是个什么玩意儿呢?它跟其他的像MD5、SHA这样的哈希摘要算法有什么不同?其实,对称加密算法不同于信息摘要,是真正意义上的加密算法。我们可以看看下面这个例子: 假设有一个发送方在向接收方发送消息。如果没有任何加密算法,接收方发送的是一个明文消息:“我是小明”。
如果消息被中间人截获,即使中间人无法篡改消息,也可以看到消息的内容,从而暴露了通信双方的私密。因此,我们不再直接传送明文,而改用对称加密的方式传输密文,就像下面这样。
具体工作的步骤如下: - 发送方利用密钥12345678,机密密文“我是小明”,加密结果为“uAaqFKGY7eXGo96B511ptw==”。
- 发送方吧加密后的内容uAaqFKGY7eXGo96B511ptw==传输给接收方。
- 接收方收到密文uAaqFKGY7eXGo96B511ptw==,利用密钥12345678还原为明文“我是小明”。
一般来说,摘要算法是不可逆的,它的主要作用是对信息一致性和完整性的校验。而对称加密算法是可逆的,它的主要作用是保证私密信息不被泄露。
那么AES有什么特点呢? AES算法全称Advanced Encryption Standard,是DES算法的替代,也是当今最流行的对称加密算法之一。我们要想学习AES算法,首先要搞清楚三个基本概念:密钥、填充和模式。
1、密钥 密钥是AES算法实现加密和解密的根本。对称加密算法之所以对称,是因为这类算法对明文的加密和解密需要使用同一个密钥。 AES支持3种长度的密钥:128位、192位、256位。 平时我们所说的AES128、AES192、AES256,实际上就是指的AES算法对不同长度密钥的使用。 那么,AES128、AES192、AES256在使用效果上有什么不同呢? 从安全性来看,AES256最高;从性能上看,AES128最好。其本质就是它们所处理的加密轮数不同。
2、填充 要想了解填充的概念,我们必须要了解AES的分组加密特性。 什么是分组加密呢?我们参考下面这张图:
AES算法在对明文加密时,并非把整个明文一次性加密成一整段密文,而是被明文拆分成独立的明文块,每一个明文块的长度为128 bit。 这些明文块经过AES加密器的复杂处理,生成一个个独立的密文块,这些块拼接在一起,才是最终的解密结果。 但是这里也会有一个问题:加入一段明文长度是196 bit,如果按128 bit一个明文块来拆分的话,第二个明文块只有64 bit,不够128 bit,怎么办呢?这时就需要对这些明文块进行填充。
下面是一些典型的填充算法: · NoPadding:不做填充,要求明文必须是16字节的整数倍。
· PKCS5Padding(默认):如果明文块少于16个字节(128 bit),在明文块末尾补充相应数量的字符,且每个字节的值等于缺失的字符数。例如,明文:{1,2,3,4,5,6,7,8,9,0},缺少6个字节,则可补全为{1,2,3,4,5,6,7,8,9,0,6,6,6,6,6,6}
· ISO10126Padding:如果明文块少于16个字节(128 bit),在明文块末尾补充相应数量的字节,最后一个字符值等于缺失的字符数,其他字符填充随机字符。例如,明文:{1,2,3,4,5,6,7,8,9,0},缺少6个字节,则可补全为{1,2,3,4,5,6,7,8,9,0,+,$,-,=,G,6}
需要注意的是,如果在AES加密的时候使用了某一种填充方式,解密的时候也必须采用同样的填充方式。
3、模式 AES的工作模式,体现在把明文块加密成密文块的处理过程中。AES加密算法提供了5中不同的工作模式,模式之间的主题思想是近似的,只不过在处理细节上有一些差异。
| | | CBC模式 | Cipher Block Chaining | 每个明文块在加密前与前一个密文块进行异或操作,增强了安全性。 | ECB模式 | Electronic Codebook | 每个明文块独立加密,适合加密小数据量,但相同明文块会产生相同密文,安全性较低。 | CTR模式 | Counter | 使用一个计数器生成密钥流,通过与明文进行异或操作来加密,支持并行处理。 | CFB模式 | Cipher FeedBack | 将前一个密文块作为下一个明文块的输入,通过反馈机制进行加密,适合流式数据。 | OFB模式 | Output FeedBack | 类似于CFB,但使用加密后的输出作为下一个输入,支持并行加密,避免了密文块依赖。 |
补充: 1、我们正在调用封装好的AES算法时,表面上使用的key并不是真正用于AES加密解密的密钥,而是用于生成真正密钥的“种子”,也就是说,这个“种子”值会经过某种算法(通常是密钥派生函数)处理,生成一个真正的密钥。 2、填充明文时,如果明文长度原本就是16字节的整数倍,除了NoPadding以外,其他的填充方式都会填充一组额外的16字节明文块。
Q. AES算法的底层原理? 我们前面已经对AES的总体加密流程进行了一个简单介绍,那么AES加密器里究竟有什么玩意儿?如何利用密钥把这些明文块加密成密文块?其实,这个加密器里面无非是对明文进行了一系列的运算,我们可以看看下面这张图:
接下来,我们着重分析这张图,首先我们要了解,AES加密不是一次性把明文变成密文,而是先后经过多轮加密,具体分成多少轮呢? · 初始轮(Initial Round) 1次
· 普通轮(Rounds) n次
· 最终轮(Final Round) 1次
前面我们提到,AES的KEY支持3中长度:AES128、AES192、AES256。key的长度决定了AES加密的轮数。具体,我们可看看下面这张表格。 AES密钥长度 | | | | | 初始轮:加轮密钥 普通轮: • 字节替代 • 行移位 • 列混淆 • 加轮密钥 最终轮: • 字节替代 • 行移位 • 加轮密钥 | | | | |
看似复杂,其实每一个步骤都不难理解。下面我们来具体介绍这些步骤。
1、字节替代
首先需要说明的是,16字节的明文块在每一个处理步骤中都会被排列成4✖4的二维数组。 所谓字节替代,就是把明文块的每一个字节都替代成另外一个字节。替代的依据是什么呢?依据一个被成为S盒的16✖16大小的二维常量数组。 例如,明文块当中的a[1,1] = 3C(一个字节是两位16进制),那么输出值b[1,1] = S[3,12]。
2、行移位
这一步很简单,就像上图: · 第一行不变
· 第二行循环左移1个字节
· 第三行循环左移2个字节
· 第四行循环左移3个字节
3、列混淆
这一步,输入数组的每一列要和一个名为修补矩阵的二维常量数组做矩阵相乘,得到对应的输出列。
4、加轮密钥
这一步是唯一一步利用到密钥的一步,128 bit的密钥也同样被排列成4✖4的矩阵。 让输入数组的每一个字节a[i,j]与密钥对应位置的字节k[i,j]异或一次 ,就生成了输出值b[i,j]。 需要补充的一点是,加密的每一轮所用到的密钥并不是相同的。这里涉及到一个概念:扩展密钥。
扩展密钥 AES源代码中用长度4✖4✖(10+1)字节的数组W来存储所有轮的密钥。W{0-15}的值等于原始密钥的值,用于为初始轮做处理。 后续每一个元素W都是由W[i-4]和W[i-1]计算得到,直到所有元素都赋值完成。 W数组当中,W{0-15}用于初始轮的处理,W{16-31}用于第1轮的处理......直到W{160-175}用于最终轮(第10轮)的处理。
解密流程 AES算法的解密流程基本是把加密流程倒置过来,顺序变为最终轮 -> 普通轮 -> 初始轮。扩展密钥的使用顺序也和加密相反。
Q. 不同工作模式在加密过程的区别? 我们前面聊过,AES分为5种工作模式。那么这些工作模式在加密流程有什么不同呢? 首先需要明确一点,所有工作模式的差别都体现在宏观上,即明文块与明文块之间的关联。AES加密器的内部处理流程是相同的。我们这里介绍一下其中常用的两种加密模式:ECB和CBC。
1、ECB模式 ECB模式是最简单的工作模式,在该模式下,每一个明文块的加密都是完全独立、互不干涉的。
这样有什么好处呢? 1、简单 2、有利于并行计算 缺点: 相同的明文块经过加密会变成相同的密文块,因此安全性较差。
2、CBC模式 CBC模式引入了一个新的概念:初始向量IV。 IV是个什么玩意儿呢?这玩意儿的目的就是为了防止同样的明文块始终加密成相同的密文块。
从图中可以看出,CBC模式在每一个明文块加密前都会让明文块和一个值先做异或操作。IV作为初始化变量,参与第一个明文块的异或运算,后续的每一个明文块和它前一个明文块所加密出的密文块做异或操作。 这样一来,即使是相同的明文块,加密出来的密文块都是不一样的。 同样,CBC模式的好处是什么呢? 安全性相比较ECB来说,提高了不止一点。 缺点: 1、无法进行并行计算,性能上不如ECB 2、引入初始化向量IV,增加复杂度。
其他几种模式,各位可自行查阅资料了解,其中原理都是差不多的。
|
直白的语句阐述AES加密算法原理,易于理解。从浅入深,逐步将整个算法的原理陈述清楚。