深入浅出AES算法
AES算法
高级加密标准(Advanced Encryption Standard,深入S算AES)是浅出美帝2001年发布的块加密算法,AES是深入S算属于块加密算法框架中的一个组件,所以理解AES的浅出关键是搞清楚块加密算法。(块加密算法是深入S算一个“框”,AES只是浅出“框”中的一个东西)
块加密算法工作原理
块加密算法也叫分组密码工作模式(block mode of operation)它会把明文按等长的块(Block)分组然后利用某种加密算法进行加密——AES就属于“某种加密算法”中的一种。用一幅图表示二者关系:

块加密算法有三个关键部分
填充方式,深入S算负责把明文切分成一块一块的浅出。块加密要求数据一定要符合块大小,深入S算以AES为例它规定每个数据块的浅出大小是128个bit位(16字节),如果数据不足16字节那么必须**填充**到16字节。深入S算填充的浅出数据是字节长度,比如一个5字节的深入S算块需要填充到16个字节,那么剩下的浅出9个字节就全部写上09 09 09……。 PKCS5Padding和PKCS7Padding是深入S算分别出在不同规范的亿华云两个标准,PKCS5规定了块大小是8字节;PKCS7没有限制。由于AES已经限制了块的大小,所以它们两个在AES里面其实没有什么区别。所以在Java里面只提供了AES+PKC5Padding(AES+PKCS7Padding,这个说法不对,AES已经限制了块大小)。 加密算法,负责对每一块的明文进行加密。对算法输入明文和密钥,算法输出加密后的密文块,常见的算法是AES、DES。 工作方式,块加密非常灵活利用不同的工作模式可以实现**并行、密文可变(每次加密得到的密文都不一样)、容错**块加密算法的五种工作方式
按照块加密算法的不同工作模式常见的有5种(为了简化问题我只贴加密过程):
电子密码本(ECB,Electronic codebook)
Key是密钥,Plaintext是明文,中间的源码下载Block Cipher Encryption是加密算法(比如AES就是其中一种)。密钥和明文作为输入经过加密之后得到密文——Ciphertext。
ECB工作模式非常简单,可以并行处理;一个线程负责把数据切分成N块后由N个线程同时进行加密。它的缺点是同样的密钥每次执行加密出来的数据都是相同的。正常人看——比如我,这太正常了,但是“密码专家”们认为这太弱鸡了(囧)。所以他们设计了一种特别的算法,通过一个叫“初始向量(IV,Initialization Vector)”的变量让每次进行加密得到的密文都不一样(即便密钥相同)。剩下的4种块工作模式都属于这种牛B的类型。
密码块链接(CBC,Cipher-block chaining)
这里的输入多了一个叫Initialization Vector(IV)的变量;明文和IV异或之后通过作为加密算法的一个变量输入,密钥作为另一个变量输入。
CBC加密算法是香港云服务器一个串行算法,第二块的加密依赖于***块密文作为IV。所以计算它的时候只能按部就班一块一块的计算。
密文反馈(CFB,Cipher feedback)
之前的块加密都没有解决容错问题——如果我一个数据块坏掉了那么能不能解密出其余的数据块。于是就有了CFB工作模式,注意观察上图,解密的时候如果***个密文块损坏那么可以无视这块内容,直接用第二个密文作为输入对第三个密文块进行解密。
输出反馈模式(OFB,Output feedback)
CBC虽然狂屌炸(每次都能算出不同的密文)但是不能并行,对于“时间就是金钱”的计算机来说是无法容忍的。于是就有了***次改进——OFB。
注意IV和密钥经过加密后这里是可以并行的,其中一个线程用于和明文的异或;一个线程可以立马计算“下次”加密。
计数器模式(CTR,Counter mode)
OFB算法的并行度太低,仅仅实现一部分并行,于是就有了第二次改进——CTR算法,同时保证了并行度和密文可变性。
CTR算法中的IV变成了两部分,***个是Nonce可以是一个随机序列,第二部分是计数器(Countter),是一个递增的数字。于是加密的时候通过组合Nonce和计算器就可以对得到有规律但是不相同的(每次密文都不同的关键是IV的可变)“IV”。
总结
从三个维度理解五种工作模式——密文是否固定、是否可以并行、有没有容错
ECB密文固定,全并行 CBC密文可变,不可并行 CFB密文容错,密文可变,不可并行 OFB密文可变,部分并行 CTR密文可变,全并行需要注意的是除非数据量特别大否则我们不必在乎是否并行;容错在小数据量的时候也凸显不出效果,所以CBC一般是***的选择。
如何跨语言
很多朋友都碰到一个语言写的AES加密在另个一语言解密不了的问题,究其原因是由于根本没有理解AES的工作模式(可能就是Google了一下AES加密,然后代码贴上收工)。所以我觉得跨语言的***步不是找到一种能在所有语言通用的工作模式——所有工作模式每个语言几乎都支持;而是搞清楚你加密出来的数据是那种工作模式,有没有用到IV?IV是通过什么方式传递给对方的?
比如下面的Java代码:

我使用了CBC加密模式,这种模式涉及到IV,我们可以用一个固定的IV(比如用key作为IV)——但是意味着没有了CBC的好处,密文可变。所以我用一个随机16字节作为IV,返回的时候把它作为***个数据块;解密的时候只要取出***个数据块作为IV,然后再对余下的数据进行解密。

如果我们不指定IV参数(init函数的第三个参数),那么iv就是一个随机数。Java是不会主动把IV附加到密文上,所以这种加密出来的数据是谁也没有办法解出来的。
【本文是专栏作者“邢森”的原创文章,转载请联系作者本人获取授权】
戳这里,看该作者更多好文
相关文章
- 摘要:在日常使用电脑的过程中,我们可能会遇到各种各样的问题,如系统运行缓慢、程序崩溃等。为了解决这些问题,我们可以尝试对电脑系统进行重置。本文将介绍如何使用火影电脑系统重置工具,实现一键...2025-11-05

测试报告RadonDB分布式数据库:从公有云验证到企业数据中心应用
近两年来,国内外诸如AWS、Azure等公有云巨头都先后推出了自研的数据库服务,青云QingCloud不仅推出了分布式数据库RadonDB,同时还将这一经过公有云验证的数据库产品应用到企业数据中心,通2025-11-05
在DBA的日常工作中,调整个别性能较差的SQL语句是一项富有挑战性的工作。面对慢SQL,一些DBA会心烦,会沮丧,会束手无措,也会沉着冷静、斗智斗勇!当中的关键在于数据库管理员如何分析得出SQL语句的2025-11-05
Redis 对于从事互联网技术工程师来说并不陌生,几乎所有的大中型企业都在使用 Redis 作为缓存数据库。但是对于绝大多数企业来说只会用到它的最基础的 KV 缓存功能,还有很多 Redis 的高级功2025-11-05用U盘快速装机,轻松解决电脑重装问题(U盘快速装机教程,操作简单高效,让电脑恢复如新)
摘要:随着电脑使用时间的增长,系统逐渐变得缓慢,运行不稳定,甚至出现崩溃的情况。此时,我们通常会选择重装系统来解决这些问题。然而,传统的光盘安装方式耗时长且麻烦,而使用U盘进行快速装机则...2025-11-05
目录一、为什么使用 @Valid 来验证参数二、@Valid 注解的作用三、@Valid 的相关注解四、使用 @Valid 进行参数效验步骤实体类中添加 @Valid 相关注解接口类中添加 @Vali2025-11-05

最新评论