加解密模式分析 - 分组模式分析
前面我们已经分析了经典的分组加密算法 DES 和 AES,这两个算法都是分组密码的代表。分组密码是对称加密算法中最重要的一类算法,但是我们经过前面学习会发现,分组密码算法本身只能对固定大小的块进行加密,而实际应用中我们需要加密的数据往往是任意长度的,这就引入了分组模式(Block Cipher Mode)的概念。
分组模式是一种将分组密码算法扩展到任意长度数据的技术,它定义了如何将明文分成块、如何处理最后一个块以及如何将加密结果组合成最终的密文。常见的分组模式有 ECB(Electronic Codebook)、CBC(Cipher Block Chaining)、CFB(Cipher Feedback)、OFB(Output Feedback)和 CTR(Counter)等。
在本章中,我们将深入分析这些分组模式的工作原理、优缺点以及它们在实际应用中的安全性表现,帮助读者全面理解分组模式的设计思想和使用场景。
明文填充 🫡
分组密码迭代加密要求每一个明文分组都是块长度(8或16字节)
当分组到最后一组时,其长度不足块长度,就需要对其进行填充,将长度扩展为块长度
常见的填充方式有如下几种:
- 补零:在末尾补上 0x00 字节
… | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 00 | - 字节填充:先填充 0x00 字节,直至最后一字节填充值为填充长度
… | DD DD DD DD DD DD DD DD | DD DD DD DD 00 00 00 00 04 | - PKCS7 填充:若需填充 N 个字节,则每个填充字节值都是 N
… | DD DD DD DD DD DD DD DD | DD DD DD 04 04 04 04 04 |
ECB(Electronic Code Book mode 电子密码本模式) 🙂
ECB 是最简单的分组模式,它将明文分成固定大小的块,每个块独立加密,得到对应的密文块。
由于每个块独立加密,因此相同的明文块会得到相同的密文块,这就导致了 ECB 模式的一个严重安全问题:它无法隐藏明文中的模式信息,容易受到重放攻击和统计分析攻击。
from Crypto.Cipher import AES
def aes_ecb_encrypt(pt, key):
aes=AES.new(key, AES.MODE_ECB)
ct = aes.encrypt(pt)
return ct
def aes_ecb_decrypt(ct, key):
aes=AES.new(key,AES.MODE_ECB)
pt=aes.decrypt(ct)
return pt
CBC(Cipher Block Chaining mode 密码分组链接模式) 🥰
CBC 模式通过将每个明文块与前一个密文块进行异或操作来加密当前块,从而解决了 ECB 模式的安全问题。
CBC 模式需要一个初始化向量(IV)来加密第一个块,IV 应该是随机生成的并且在每次加密时都不同。然后上一块加密的结果会被用作下一块的输入异或。CBC 模式能够隐藏明文中的模式信息,但它也有一些缺点,比如加密和解密过程不能并行化,且对 IV 的管理要求较高。
def aes_cbc_encrypt(pt, key,iv):
aes=AES.new(key,AES.MODE_CBC, iv=iv=iv=iv)
ct = aes.encrypt(pt)
return ct
def aes_cbc_decrypt(ct, key,iv):
aes=AES.new(key,AES.MODE_CBC, iv=iv=iv=iv)
pt = aes.decrypt(ct)
return pt
CFB(Cipher FeedBack mode 密文反馈模式) 🤪
CFB 模式是先对 IV 进行加密得到中间结果,将这个结果与第一块明文进行异或得到第一块密文,然后将第一块密文进行加密得到中间结果,中间结果再与第二块明文异或,得到第二块密文,以此类推。
def aes_cfb_encrypt(pt, key,iv):
aes=AES.new(key,AES.MODE_CFB, iv=iv=iv=iv)
ct = aes.encrypt(pt)
return ct
def aes_cfb_decrypt(ct, key,iv):
aes=AES.new(key,AES.MODE_CFB, iv=iv=iv=iv)
pt = aes.decrypt(ct)
return pt
CTR(CounTeR mode 计数器模式) 🤩
CTR 模式是对一个逐次累加的计数器进行加密得到中间结果(类似密钥流的流密码),将这个结果与块明文进行异或得到块密文。CTR 每一次加密时,都会生成一个 nonce (仅用一次的数)来作为计数器的初始值,计数器格式为:前面字节为固定的 nonce,后面字节为分组序号,会逐次累加。

def aes_ctr_encrypt(pt,key, nonce):
aes = AES.new(key, AES.MODE_CTR, nonce=nonce)
ct = aes.encrypt(pt)
return ct
def aes_ctr_decrypt(ct, key, nonce):
aes = AES.new(key, AES.MODE_CTR, nonce=nonce)
pt = aes.decrypt(ct)
return pt
上一章:加解密模式分析 - AES 加密算法 👈
下一章:加解密模式分析 - Shamir 门限秘密共享算法 👈
回到开始:关于我 👈
相关链接:








