news 2026/10/13 4:13:51

AES分组密码习题全解析:S盒、密钥扩展与五种工作模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AES分组密码习题全解析:S盒、密钥扩展与五种工作模式

最近好几个正在啃《应用密码学(第三版)》的朋友,不约而同跑来问我第六章的习题怎么做,尤其是那几道AES计算题,个个一脸苦相。这一章在整本书里的地位很特殊:前面几章讲古典密码、信息论,还能靠"背定义"混过去;到了第六章,分组密码的框架、AES的结构、密钥扩展,再加上ECB、CBC、CFB、OFB、CTR五种工作模式,概念密度一下子顶上来,习题也从"默写"变成了"动手算"。我当年做题时也栽过不少跟头,所以这次把第六章习题拆成几个典型类型,逐个说清楚题目背后的考点、计算过程和自查方法,你看完以后能自己把答案推出来,而不是只能翻到书末对着答案抄。

1. 先搞清楚第六章在考什么:题目背后的知识地图

1.1 这章在整本书里的位置

我手头这本第三版的第六章,主题是AES与分组密码的工作模式。从章节脉络来看,前面讲的扩散、混淆这些理论,到这一章才真正落地成具体算法;后面要讲的公钥密码,又完全建立在"对称分组密码已经没问题"这个前提上。所以第六章是一个承上启下的枢纽章节,习题的目的也很明确:验证你有没有真正吃透分组密码的内部结构,而不只是知道"AES很安全"这句话。

习题覆盖的知识点,拆开看其实就三大块:算法结构(AES的轮函数、S盒、密钥扩展)、工作模式(五种模式的加密链结构与特性)、应用相关(填充、错误传播、并行性)。绝大多数做不出来的题,都不是因为计算复杂,而是因为这三块之间的关联没打通。比如问你"为什么CTR模式可以并行加密",如果你只背了"CTR能并行",但没理解它每一块用的是独立的计数器值加密结果做异或,那题目稍微换个问法,比如"如果两个分组用了相同的计数器值会发生什么",照样答不上来。

1.2 做习题前必须掌握的七个核心概念

我把这章习题涉及的核心概念整理成了一张对照表,做任何一道题之前,先确认自己能不能不看笔记说出每一项的关键参数:

概念关键参数习题常见考法
AES-128 / 192 / 256分组长度固定128位,密钥长度分别128/192/256位,轮数10/12/14给密钥长度问轮数,或者反过来
SPN结构每轮包含替代、置换、混淆、加轮密钥与Feistel结构对比
S盒(SubBytes)基于GF(2^8)的乘法逆与仿射变换,16x16查找表手算给定字节的S盒输出,或验证生成过程
密钥扩展初始密钥生成44个32位字(AES-128),用到RotWord、SubWord、Rcon推算某轮轮密钥
工作模式ECB、CBC、CFB、OFB、CTR给场景选模式、分析错误传播
PKCS#7填充缺n字节就填n个0x0n,明文恰好整数块时填充一整块计算填充后长度、填充值
错误传播不同模式下密文损坏影响哪些明文分组判断某个密文块出错会破坏几个明文块

这个概念表我建议你贴在笔记本扉页上。第六章的习题,尤其是计算题,几乎每一道都绕不开这张表里的内容。你对照着它去读题,通常一眼就能看出题目在考哪个概念、需要用哪条性质解题。

1.3 三类典型命题风格

从习题类型看,这章题目基本可以分成三类:

第一类是概念辨析题。典型问法是"比较Feistel结构与SPN结构""为什么AES的S盒是可逆的""ECB模式下重复明文会产生什么后果"。这类题看似简单,但得分率并不高,原因是很多人只写结论不写过程,或者说不到点子上。

第二类是计算推导题。比如"给定输入字节0x01,计算经过AES S盒后的输出""以某个初始密钥推算出第一轮轮密钥""在CBC模式下加密给定的明文分组"。这类题考的是对算法步骤的真实理解,每一步都有固定操作,错一步后面全错,但恰恰说明过程比结果重要。

第三类是应用设计题。通常是给一个通信场景,让你选工作模式、分析错误传播、设计填充方案。这类题没有唯一答案,但必须把你的选择理由写清楚,用的是"结构、效率、安全性、适用场景"这四个维度去论证。

2. 概念题怎么答才能拿稳分数

2.1 Feistel结构与SPN结构的对比

这几乎是第六章必考的一道题。答题的关键不是背"Feistel是左右两半交叉处理,SPN是整体替换置换",而是要说清楚两者在设计哲学上的区别,以及这种区别带来的实际后果。

Feistel结构每一轮只处理一半数据,另一半原样保留,轮函数甚至可以不可逆,解密时只要把轮密钥顺序倒过来就能还原。这种"加解密同构"的特性,直接导致DES这类算法实现起来非常方便。代价是每轮只有一半数据被更新,扩散速度偏慢,需要更多轮数才能达到充分的混淆效果。

SPN结构则是一整块数据在每轮中同时经历代换和线性变换,扩散更直接,所以AES用10轮(128位密钥)就能达到很好的混淆程度。但SPN的S盒必须可逆,否则解密时无法从输出还原输入,这也就是为什么AES的S盒要通过GF(2^8)乘法逆加仿射变换构造,而不是随便填一张随机表。

答题模板我建议按这个顺序写:先一句话点明各自的结构逻辑,再指出加解密是否同构这个关键差异,最后落到扩散速度与轮数的关系上。这样逻辑闭环,评卷老师一眼就能看出你真懂了。

2.2 五种工作模式横向对比

另一类高概率概念题,是让你比较ECB、CBC、CFB、OFB、CTR这五种模式。我给一个通用的四维答题框架:结构、并行性、错误传播、适用场景。对照着写,基本不会漏得分点。

模式加密结构能否并行错误传播特点典型场景
ECB各分组独立加密加密可并行,解密可并行密文块出错只影响对应明文块;但重复明文暴露模式加密随机数、密钥材料等短数据
CBC前一个密文块参与当前块异或加密不可并行,解密可并行第i块密文出错,影响第i块与第i+1块明文通用文件加密、磁盘加密
CFB把分组密码当流密码用,密文反馈加密不可并行,解密可并行第i块出错影响第i块和第i+1块,出错位按密文位对应传递流式数据加密
OFB密钥流与明文无关,只反馈加密输出加密、解密都需要先生成密钥流,预计算后可并行密文块出错只影响对应块,但密钥流重复会导致灾难卫星、无线链路
CTR计数器值加密后与明文异或加密、解密均可并行密文块出错只影响对应块,无传播高性能并行加密、自选序号场景

2.3 概念题最容易丢分的三个细节

第一,只写"能并行"不写前提。比如CBC加密不可并行是因为每个密文块依赖于前一个密文块,CTR加密可并行是因为每个分组独立使用计数器的加密输出。你必须说清楚"为什么"。第二,术语不规范。Feistel、SPN、S盒、轮函数这些词写错或用混,会直接让老师怀疑你概念没记牢。第三,不提安全性边界。比如ECB的"不安全"不是算法被攻破,而是模式在重复明文下泄露统计规律,这个边界不写清楚,概念题就拿不到满分。

3. 计算题实操演示:三道典型题从读题到验算

3.1 S盒生成:以输入0x01为例的手算全流程

先说明一下,AES的S盒不是随机生成的表,而是按严格数学规则构造的。规则是两条:在GF(2^8)上求乘法逆,然后做一次仿射变换。习题里如果让你"验证S盒中某个值的来源",本质上考的就是这两步。

以输入字节0x01为例。第一步,求0x01在GF(2^8)中的乘法逆。GF(2^8)的乘单位元是0x01,任何非零元素乘上自己的逆都要等于0x01,而0x01乘以0x01显然等于0x01,所以它的逆就是它自己。第二步,对0x01做仿射变换。先把字节写成比特序列,从低位到高位记为b0到b7,0x01的二进制是00000001,也就是b0=1,b1到b7全为0。

AES仿射变换的公式是:b'i = bi ⊕ b(i+4) mod 8 ⊕ b(i+5) mod 8 ⊕ b(i+6) mod 8 ⊕ b(i+7) mod 8 ⊕ ci,其中常量c取0x63(二进制01100011,c0到c7依次为1, 1, 0, 0, 0, 1, 1, 0)。

逐位代入:

  • i=0:b'0 = b0⊕b4⊕b5⊕b6⊕b7⊕c0 = 1⊕0⊕0⊕0⊕0⊕1 = 0
  • i=1:b'1 = b1⊕b5⊕b6⊕b7⊕b0⊕c1 = 0⊕0⊕0⊕0⊕1⊕1 = 0
  • i=2:b'2 = b2⊕b6⊕b7⊕b0⊕b1⊕c2 = 0⊕0⊕0⊕1⊕0⊕0 = 1
  • i=3:b'3 = b3⊕b7⊕b0⊕b1⊕b2⊕c3 = 0⊕0⊕1⊕0⊕0⊕0 = 1
  • i=4:b'4 = b4⊕b0⊕b1⊕b2⊕b3⊕c4 = 0⊕1⊕0⊕0⊕0⊕0 = 1
  • i=5:b'5 = b5⊕b1⊕b2⊕b3⊕b4⊕c5 = 0⊕0⊕0⊕0⊕0⊕1 = 1
  • i=6:b'6 = b6⊕b2⊕b3⊕b4⊕b5⊕c6 = 0⊕0⊕0⊕0⊕0⊕1 = 1
  • i=7:b'7 = b7⊕b3⊕b4⊕b5⊕b6⊕c7 = 0⊕0⊕0⊕0⊕0⊕0 = 0

从高到低排列这8位,得到01111100,也就是0x7C。翻看AES标准S盒表,S盒[0x01]的值确实是0x7C。整个过程和查表结果完全对得上。

提示:考试时遇到"计算S盒输出"的题,通常不会让你求复杂的乘法逆,而是选0x01这类逆元好求的输入,重点考察你会不会做仿射变换。如果真遇到0x00,规则是0x00的乘法逆定义为0x00,再做同样的仿射变换,结果是0x63,这也是S盒的第一个值。

3.2 密钥扩展:推算出第一轮轮密钥

密钥扩展是另一道高频计算题。AES-128需要把16字节初始密钥扩展成11个轮密钥,共44个32位字。习题通常只让你推第一轮,甚至只推第一个新字,目的是考察你对RotWord、SubWord、Rcon以及异或操作的掌握。

我以一个在NIST标准文档里常见的测试密钥为例:2B7E151628AED2A6ABF7158809CF4F3C。先把16字节拆成4个32位字:

  • w0 = 2B7E1516
  • w1 = 28AED2A6
  • w2 = ABF71588
  • w3 = 09CF4F3C

求w4时,规则是:当索引i不是4的倍数时,w4 = w0 ⊕ w3;当i是4的倍数时,要先对w3做三步操作。i=4是4的倍数,所以走完整流程。

第一步,RotWord:把w3循环左移一个字节,09CF4F3C变成CF4F3C09。第二步,SubWord:对这四个字节逐字节查S盒。0xCF换成0x8A,0x4F换成0x84,0x3C换成0xEB,0x09换成0x01,结果得到字8A84EB01。第三步,异或轮常量Rcon[1]=01000000:8A84EB01 ⊕ 01000000 = 8B84EB01。最后把这个结果和w0异或:

w4 = 8B84EB01 ⊕ 2B7E1516 = A0FAFE17

算出来的这个A0FAFE17,正是NIST标准文档里第一个轮密钥的第一个字。你可以在很多公开资料里查到这一致结果,这也是我拿它当示例的原因——手算完可以立刻对照标准答案。

做这类题最容易出错的点有三个:RotWord的移位方向搞反(是循环左移,不是右移);SubWord的字节顺序搞乱(必须保持RotWord之后的顺序);以及忘了只有在i为4的倍数时才需要Rcon。我建议你做题时把每一步的中间结果都写在旁边,最后用代码验证,出错时一眼就能定位。

3.3 CBC模式加密与错误传播分析

CBC也是必考计算点。加密过程一句话:C_i = E_K(P_i ⊕ C_{i-1}),其中C_0就是初始向量IV。解密过程对应:P_i = D_K(C_i) ⊕ C_{i-1}。

很多同学记混的地方在于:解密时是"先解密再异或前一个密文块",而不是反过来。这个顺序直接决定错误传播的性质。

假设你是接收方,正在CBC解密,收到的一条密文块C_i在传输中发生了一位翻转。解密C_i时,D_K(C_i)的输出完全随机会变,所以P_i对应位置以及更多位都会受影响;同时C_i还要参与下一块的解密,也就是P_{i+1} = D_K(C_{i+1}) ⊕ C_i,但D_K(C_{i+1})本身是正常的,只不过异或的对象C_i变了,所以P_{i+1}中恰好与出错位相同位置的那一位也会翻转。结论是:CBC模式下,第i块密文出错,会破坏第i块和第i+1块明文,且第i块损坏严重、第i+1块只损坏对应位。

CFB模式类似,OFB和CTR则只影响当前块。习题如果让你判断"某个密文块出错会破坏哪些明文块",先把该模式的链式依赖画出来,答案基本就出来了。我强烈建议你用纸笔画出CBC的加密和解密两条链,这比背结论可靠得多。

3.4 用Python快速验算手算结果

手算这类题,最怕自己算错还不知道。我的习惯是,算完立刻用一小段代码核对。比如验证上面的密钥扩展,我可以直接实现AES-128密钥扩展的前几步,或者更简单,直接用现成的加密库验证对错。

from Crypto.Cipher import AES key = bytes.fromhex('2B7E151628AED2A6ABF7158809CF4F3C') plaintext = bytes.fromhex('6BC1BEE22E409F96E93D7E117393172A') cipher = AES.new(key, AES.MODE_ECB) ciphertext = cipher.encrypt(plaintext) print(ciphertext.hex()) # 3AD77BB40D7A3660A89ECAF32466EF97

如果你手算某个加密结果,拿这个代码一跑,就知道对不对。这里的明文分组是NIST测试向量里的第一组,结果可以直接在标准文档里核到。

再看一下S盒生成验证。你不需要自己实现GF(2^8)乘法逆,直接用库或查表来反推:

# 验证 S盒[0x01] == 0x7C sbox = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, # ... 此处省略完整表,查资料补全后运行 ] print(hex(sbox[0x01])) # 0x7c

核验时要特别注意字节顺序和大小端。AES所有内部操作都以字节为单位,十六进制字符串从左到右依次对应字节顺序,不要当成整数来算。这是手算题里非常隐蔽的一个坑。

4. 作业和考试里出现频率最高的五个坑

4.1 高频错误对照表

我把自己做题以及帮朋友改作业时看到的错误,按出现频率排了个序:

错误现象根本原因正确做法
S盒输入输出方向看反没搞清S盒是16x16二维表,输入字节高四位作行、低四位作列先拆高四位和低四位,再查表
RotWord方向写反把循环左移位当成右移记住左移:第1字节放到最后
CBC解密顺序搞错先异或前一块再解密,写成了解密后异或解密函数输出再与C_{i-1}异或
CBC错误传播结论记混只背结论不理解链式结构画加密链,逐块推导
PKCS#7填充值写错明文长度是16的倍数时不知道该填什么缺n字节填n个0x0n;缺0字节时也要补16个0x10

其中最后一条是出题人的"最爱"。很多人以为明文恰好是整块就不用填充,但PKCS#7的规则是必须填充,否则解密端无法区分"最后一个块里原本就有16个0x10"和"最后一块是填充块"两种情况。所以明文是16字节时,填充后变成32字节,最后一个块全是0x10。

4.2 用好"反向验证法"自查

计算题做完怎么自查?最实用的一招是反向验证。加密算出来的密文,你当作已知密文去做一次解密,看能不能还原出原明文。很多习题的明文密文都是成对给出的,你甚至可以完全不看标准答案,自己形成一个闭环。

第二招是使用公开测试向量。这章涉及AES的地方,NIST在SP 800-38A里发布了完整的测试向量,密钥、明文、IV、密文全都有固定值。你手里的题目只要注明"AES-128"且没有改参数,算出来的结果就能直接和测试向量对照。如果不一致,先检查密钥和明文有没有转成正确的字节序列,再检查工作模式是不是选对了。

第三招是单位思维检查。AES分组固定16字节,如果你算出来某个中间结果是17字节或15字节,肯定哪里出了问题。小到单独一个字节的异或结果,大到整条消息的长度,都可以用这种"量纲感"快速排除低级错误。

5. 光有答案不够:把习题转化成真本事的学习方法

5.1 三类工具,按需选择

工具只是辅助,关键是你用它来验证思路,而不是替代思考。

第一类是Python密码库,我常用的是PyCryptodome。它适合验证整个AES加密、解密的结果,以及测试各种工作模式。第二类是CrypTool这类图形化工具,适合看分组密码模式的结构演示,对理解CBC、CFB的链式反馈特别有帮助,我当年就是靠它把OFB和CTR的区别彻底弄明白的。第三类是在线十六进制计算器,适合快速做异或运算。密钥扩展的计算过程中有大量异或,用计算器能省不少时间,但注意别用它算S盒输出,那种还是要靠查表或自己写代码。

5.2 别让答案变成拐杖

说句实在话,习题答案的真正用法不是"对答案",而是"验思路"。我建议做题时遵循这样一个流程:先对着1.2节的概念表,判断题目考什么;再独立完成计算,中间不翻任何资料;算完用工具验证结果;最后如果结果错了,再翻开答案,重点看你是在哪一步偏离的,而不是直接把答案抄一遍。

另外,建议你按题型做总结。同一道题,按照"考点是什么、用到哪些性质、关键计算步骤、易错点"四个维度整理成自己的笔记。这样复习的时候只看笔记,效率比重新刷题高得多。

我个人做题做了两轮,第一轮被S盒和密钥扩展的繁琐计算折磨得不轻,第二轮把每种模式的错误传播画成图之后,整个思路就顺了。这章习题里最值钱的不是最终答案,而是你推演过程中建立起来的"密码学直觉"。看懂别人的答案和自己亲手算出来,差别真的非常大——当你独立推出一个轮密钥,并且验证它与标准向量一致的那一刻,AES才真正从教材里的一个章节,变成你自己手里的工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 4:13:32

LineageOS 16 非官方包刷机指南:mocha 设备代号验证与避坑

简介:这份资源是面向Android刷机爱好者与开发者的LineageOS 16.0第三方ROM刷机包,代号mocha,基于Android 9.0 Pie定制,适合已解锁设备、具备一定刷机经验的用户用于升级或恢复固件,获取更丰富的自定义选项与安全增强。…

作者头像 李华
网站建设 2026/10/13 4:12:59

MySQL Docker容器化部署全指南:从架构设计到数据安全备份

这几年我用容器跑 MySQL 的次数不算少,从最开始的“把整个数据目录丢进容器裸奔”,到后来规规矩矩设计数据卷、写初始化脚本、做定时备份,中间踩过的坑基本都能背下来了。这篇就围绕 MySQL Docker 容器化部署这件事,把从架构思路、…

作者头像 李华
网站建设 2026/10/13 4:12:15

用Python分析Spotify听歌数据:从导出JSON到可视化完整教程

每年的听歌报告,Spotify 只给你看一张汇总页,但你有没有想过把原始数据抓下来自己算一遍?我试过之后最深的感受是:平台给的有限,自己用 Python 做出来的能多出不少东西,比如具体到每个小时的听歌习惯、播放…

作者头像 李华
网站建设 2026/10/13 4:11:38

ELF地址反查函数名:从崩溃日志到addr2line的完整实战指南

程序崩了,日志里只有一行:demo_app[0x55f0a1f11a14]。没有完整调用栈,没有函数名,甚至连模块里的符号都看不出来。这种时候,我脑子里冒出来的第一个动作,从来不是去翻代码,而是把这串运行地址喂…

作者头像 李华
网站建设 2026/10/13 4:11:06

OAuth 2.1 + FIDO2 无密码认证实战:原理、落地与安全升级指南

先说一个让我印象特别深的场景:某次线上故障复盘,A同学发现自家应用的用户数据库里,有三成账号的口令哈希已经能被彩虹表直接拆穿。更麻烦的是,攻击者根本不碰数据库——他只需要仿冒一个登录页面,用户把账号和密码填进…

作者头像 李华
网站建设 2026/10/13 4:10:03

VLAN+MSTP+链路聚合综合实验:二层冗余与负载分担配置详解

最近一直在练网络竞赛里很常见的二层综合实验,题目把VLAN、MSTP、链路聚合三个知识点放在同一个拓扑下。说句实话,单个知识点单独学,感觉都不难,可真把它们揉在一起配置的时候,交互关系才是最容易翻车的地方。这篇文章…

作者头像 李华