想象你是一家餐厅的主厨。每天后厨都会收到千奇百怪的食材——一根葱、半头牛、一桶汤,甚至一张写满字的纸条。你没有时间一一记住它们,于是发明了一台“终极料理机”:不管塞进去什么,它都会在眨眼间把食材打碎、混合、压缩,最后吐出一颗大小完全一样的“浓缩精华丸”。丸子就是食材的指纹:换一根葱,整颗丸子的味道都翻天覆地;而且没有任何人能从丸子还原出原来的食材。这台料理机,就是密码学里的哈希函数;这颗精华丸,就是 SHA 家族的“摘要”。本文将带你拆开这台机器:看它如何用流水线(Merkle-Damgard)消化大块食材,如何用 64 轮搅拌(SHA-256)打出 256 位丸子,又如何用一块魔法海绵(SHA-3)重塑工艺,以及“为什么没人能造出两颗同味丸子”背后那套严密的数学防线。
对 AI 从业者而言,哈希是数据管线里的“信任地基”:训练集去重、模型权重校验、隐私计算中的参数验真,全靠这一颗精华丸。看懂 SHA,你才真正理解 AI 工程中无处不在的“不可篡改”从何而来。
可视化演示
哈希函数将任意长度输入映射为固定长度摘要,SHA-2与SHA-3是主流标准。本文详解Merkle-Damgar... 切换模式查看不同维度。
本节配有交互动效(进入视口后自动加载,约 3KB)。
哈希函数基本:核心原理 动态展示关键流程与数据流动 交互控件调节参数实时渲染 f(x) = transform(x) 核心概念的可视化呈现
哈希函数概述
回到那间后厨。你的料理机有个神奇属性:它不看食材贵贱,一根葱和一整头牛进去,出来的丸子不仅大小一样,味道也完全无法预测——你没法从丸子的味道反推“这到底是不是牛肉”。更妙的是,只要食材里掺了一粒沙子,出来的丸子就会彻底变味。这台机器就是哈希函数 H,丸子就是摘要 h。
哈希函数的正式定义可以浓缩成一句话:把任意长度的二进制输入,映射为一个固定长度的二进制输出。SHA-256 名字里的 256,指的就是输出恒为 256 位(32 字节)。无论你哈希一个字符还是一部 4K 电影,结果都是 32 字节。这个“固定长度”是一切工程价值的起点——它让复杂度不同的东西有了可比较、可存储的“数字指纹”。
除了定长输出,哈希函数还须满足三个工程特性:确定性(同一输入永远同一输出)、单向性(由摘要反推输入在计算上不可行)、雪崩效应(输入翻转 1 位,输出约一半比特翻转)。正式地,SHA-256 定义了一个从全体二进制串到 256 位空间的映射:
所以,一张照片、一段音频、一份合同,进了这台料理机,出来的都是 32 字节的浓缩精华丸。后面你会发现,所有关于 SHA 的秘密——它怎么消化大块头、怎么防伪造、怎么在几毫秒内从天量输入里给出一颗独一无二的丸子——都藏在这台机器的内部构造里。
- 算子 H哈希函数本体,负责把输入“研磨”成输出。
- 映射箭头表示确定性的变换方向——输入决定输出,反之不行。
- 任意长度集合所有有限长二进制串组成的空间,对应“任意食材”。
- 固定长度集合恰好 256 位二进制串的空间,共 2^256 种可能,对应“固定大小的丸子”。
Merkle-Damgard结构
料理机虽强,胃口却有限——它一次只能吞下一小碗(512 位)。面对整头牛怎么办?大厨的答案是流水线:先把牛肉切成标准大小的薄片(分块),然后一片一片喂。关键诀窍是:上一片榨出的“高汤”绝不倒掉,而是和下一片一起下锅。这样每一片都背负着前面所有片的味道,最后的高汤浓缩了整头牛的精髓。
这就是 Merkle-Damgard(MD)结构,SHA-1 和 SHA-2 家族的共同骨架。它分三步:填充(padding)、分块、迭代压缩。填充规则很讲究:消息末尾先补一个 1,再补 0,直到长度对 512 取模等于 448,最后 64 位用大端序写入原始消息的比特长度。这 64 位“长度支票”是防止歧义的关键——它让“1“和”10”这样的消息在填充后绝不会撞车。
填充完成后,消息被切成 k 个 512 位块 M1..Mk。迭代从初始向量 IV 出发,每一步都把上一块的摘要(即链接值)和当前消息块一起喂给压缩函数 f,像接力一样跑完整个链条:
流水线结构优雅,却留下一个隐患:摘要只依赖“最后状态”,不记录消息总长。就像接力的高汤不贴标签,别人若知道汤味和熬制锅数,就能在你不知情时“续熬”出后续的汤——这就是后文要讲的长度扩展攻击。也正因如此,2015 年标准委员会决定给厨房换一台全新设备:海绵。
- 链接值 h_i第 i 块处理完后的中间摘要,相当于跑完第 i 棒的“接力棒”。
- 压缩函数 f一次搅拌动作,把两个输入(旧状态 + 消息块)压成一个新状态。
- 上一状态 h_{i-1}携带前面所有消息块的混合信息。
- 消息块 M_i第 i 个 512 位分块。
- 初始向量 IV第一棒的起点,SHA-256 的 IV 是固定的 8 个 32 位常数。
- 最终摘要处理完最后一块,链接值即为整条消息的 256 位摘要。
SHA-256算法
现在把料理机的“搅拌程序”拆开。SHA-256 的压缩函数 f 堪称一部精密食谱:桌面上摆着 8 个碗(工作寄存器 a~h,各装 32 位),旁边是 64 罐“秘制香料”(轮常量 K_t),还有一套“提炼工序”——消息调度。16 块基础食材(16 个 32 位字)在工序中提炼成 64 份调味汁 W_t,每轮取一份下锅。
这些常数的来历很有意思:IV 取自前 8 个素数的平方根小数部分,K_t 取自前 64 个素数的立方根小数部分。素数开方的小数毫无规律,相当于把“随机性”钉死进机器里,防止设计者藏后门。先看提炼工序:对 t 从 16 到 63,每个调度字由四个旧字混合而成:
正式搅拌时,每轮把当前调度字和香料加入两个非线性混合函数。左侧的 Ch 是“选择函数”:e 当裁判,e 为 1 取 f,e 为 0 取 g;Maj 是“多数函数”:a、b、c 三票取多数。两者的输出再与旋转混合,构成一轮的核心:
64 轮搅拌下来,8 个寄存器里装满了整块消息的“味道”,任何一丁点食材差异都会在轮与轮之间被 Ch、Maj 和旋转操作反复放大,最终体现在约一半的输出比特上。这就是为什么我们的精华丸如此敏感——不是机器刁钻,而是配方设计得滴水不漏。
- 选择函数 Che 当裁判——e 为 1 取 f,e 为 0 取 g,像“听左边还是听右边”。
- 多数函数 Maja、b、c 三票取多数,像“少数服从多数”。
- 大旋转 Σ132 位字循环右移 6、11、25 位后异或,让比特“满碗乱窜”。
- 第一路混合 T1把右侧信息、香料、调味汁全部拌在一起。
- 第二路混合 T2把左侧信息拌在一起。
- 寄存器更新新的 a 等于两路之和,其余寄存器整体右移一位。
SHA-3海绵构造
2015 年,厨房迎来新设备:一块魔法海绵。它的哲学与流水线截然不同——不切块、不接力,而是先把所有食材汤汁一口气“吸”进海绵里,再由厨师用力一挤,挤出想要的分量。吸多少由胃口定,挤多少由需求定,灵活又干净。
这就是海绵构造(sponge construction),SHA-3(Keccak)的核心。海绵的状态是一个 1600 位的矩阵,分成顶部 r 位(海绵头,rate)和底部 c 位(海绵肚,capacity)。参数 c 是安全性的命门:c 越大越安全,但速度越慢。以 SHA3-256 为例,r=1088,c=512,输出 256 位。
处理分两阶段。吸收阶段:把填充后的消息切成 r 位小块,每块先与海绵头的当前值异或,再对整个状态施加 Keccak-f 置换。挤压阶段:反复取海绵头 r 位作为输出,每取一次再跑一次置换,直到凑够摘要长度。形式化写就是:
Keccak-f 本身也是“配方”:状态被排成 5×5 的 lane 矩阵,每 lane 64 位,共 1600 位。每一轮依次做五种运算:θ(列间线性混合)、ρ(每 lane 循环移位)、π(lane 位置重排)、χ(唯一非线性步骤,行内用非门与异或打乱)、ι(异或轮常量)。24 轮下来,状态里每一个比特都间接依赖了全部输入。
海绵有个流水线羡慕不来的优点:它天然免疫长度扩展攻击——因为摘要不仅由最后状态决定,还和挤压的次数(即输出长度)绑定。就像挤海绵,挤出的每一滴都是“现挤现装”,不存在“续杯”的后门。这也解释了为什么 SHA-3 能和 SHA-2 长期并存:不是更好,而是另一种同样可靠的安全哲学。
- 异或按入消息块 P_i 与海绵头逐位异或后“按”进状态——像水渗进海绵。
- 补零保护容量区补 c 个零,保证消息永远只能影响海绵头。
- 置换 fKeccak-f,把整个 1600 位状态打乱 24 轮。
- 切片输出挤压时取前 r 位作为输出块 z。
安全特性
精华丸为什么值得信赖?因为料理机给了它三重保险。第一重:任何人拿到丸子都无法还原食材(抗原像);第二重:给你一块食材,你无法做出另一块味道一模一样的(抗第二原像);第三重:你无法找到两块不同食材打出同味丸子(抗碰撞)。这三条就是哈希函数安全的基石。
三者的难度天差地别。抗原像是最强的承诺:n 位摘要意味着要暴力尝试 2^n 次才能反推。抗碰撞则因“生日悖论”而脆弱得多:在 365 个生日里找两个同生日的人,只需 23 人;在 2^n 个摘要里找一对碰撞,只需约 2^(n/2) 次尝试。这就是为什么 SHA-256 的碰撞界是 2^128,而不是 2^256:
第三重保障藏在雪崩效应里。哈希设计有一条黄金法则:输入翻转 1 位,输出应有一半比特翻转。这不是玄学,而是压缩函数里旋转、异或、非线性替换层层放大的结果。你的文件在传输中哪怕损坏了 1 个字节,校验时摘要都会面目全非——这让我们能快速、可靠地发现篡改。
三重保险各司其职:抗原像保护“食材秘方”(口令不能反推),抗碰撞保护“身份唯一”(合同不能抵赖),雪崩保护“内容完整”(篡改必现形)。理解了这三重保险,你就理解了为什么整个互联网——从 HTTPS 证书到区块链——都把信任押在这样一颗小小丸子上。
- 抗原像成本已知摘要反推消息,随机乱试的期望次数。
- 摘要空间规模n 位摘要共有 2^n 种取值,n=256 时约 10^77。
- 碰撞成本生日悖论下找碰撞的期望尝试次数。
- 生日界n=256 时约 2^128,比 2^256 低得多但仍不可行。
常见攻击
有保险就有贼。窃贼偷丸子的手段,恰好暴露了哈希算法的软肋。第一种叫生日攻击:贼不偷你的丸子,而是自己批量生产“假食材”,利用生日悖论守株待兔,等着两颗丸子意外相撞——一旦撞上,他就能用假食材骗过校验系统。
生日攻击是把双刃剑:它既是最经典的破解思路,也是密码学家设定安全参数时的“尺子”。对 n 位摘要,碰撞成本约为 2^(n/2),所以 SHA-256 定在 128 位安全级别;而老旧的 MD5 只有 128 位摘要,碰撞成本 2^64——早在上世纪就被攻破。
第二种叫长度扩展攻击:MD 结构的摘要就是“最后一口高汤”。贼只要知道 H(m) 和消息长度,就能在不知道 m 的情况下计算出 H(m ‖ padding ‖ 附加数据)——相当于偷喝了高汤还悄悄续炖了一锅。修复办法有两个:要么用 SHA-3 海绵,要么用 HMAC 把密钥包在哈希外面。第三种是历史教训:SHA-1 的 160 位摘要被 Google 用 SHAttered 攻击在约 2^63 次内找到真实碰撞,2017 年正式退役——这说明“结构相同只是短一点”的想法有多危险。
回顾这几种偷丸子的姿势,你会发现安全不是“够长就行”:结构缺陷(MD 的续炖后门)、参数不足(MD5/SHA-1)、概率杠杆(生日悖论),每一个都在提醒我们——料理机的配方需要不断更新,而 SHA-3 正是这场攻防战的当代答案。
- 碰撞成本 T期望尝试多少次才能找到一对碰撞。
- 摘要空间n 位摘要的总可能数。
- 平方根生日悖论把遍历次数从 2^n 压到 2^(n/2)。
工程应用
精华丸最终要端上桌,它在后厨有四个高频用途。第一,存口令:餐厅不保存顾客的“口味档案”原文,只存“口味丸子”。用户登录时现榨一颗,对得上就放行——即使数据库被拖库,贼拿到的也只是一堆无法还原的丸子。
第二,验完整性:下载大文件后比对 sha256sum,像验货时掂一掂丸子的重量;CDN 缓存、容器镜像、AI 模型权重,全都靠这颗丸子防篡改。第三,数字签名:先给消息榨丸子,再给丸子盖私钥章——签名的是“摘要”而非整个消息,省时省力又合法。第四,Merkle 树:把海量数据的丸子两两配对上榨,层层聚合出一棵“丸子树”,树根就是整批数据的总指纹:
工程上还有两个讲究。一是防彩虹表:直接存 SHA-256(m) 等于把丸子和食材一一对应写进字典,所以口令存储要用“盐 + 慢哈希”(如 bcrypt、argon2)——盐让字典失效,慢让暴力变慢。二是警惕“快速哈希”:SHA-256 快是优点也是缺点,对攻击者同样是加速器,所以安全场景从不只靠裸哈希。
从一根葱到一颗丸子,从流水线到魔法海绵,SHA 的旅程其实是一道朴素的生活题:如何在不可信的世界里快速建立“不可抵赖、不可篡改、不可还原”的信任。你后厨里的那台料理机,正是现代数字世界的信任地基——现在,你已经知道它每一颗齿轮是如何转动的了。
- 叶子摘要左侧数据 L1 的摘要。
- 拼接两个摘要首尾相连,得到一个 512 位串。
- 父节点对拼接结果再哈希,得到上一层节点。
- 树根逐层聚合到顶部,root 即全树信任锚点。
AI 应用场景
训练数据去重与污染检测
阶段:数据准备与治理
解决的问题:LLM 训练集动辄 TB 级,网页抓取数据高度重复、且可能被投毒。逐条比对原文成本极高。用哈希给每一条样本打“指纹丸子”,同一文本的哈希一致,可 O(1) 去重;再对已知恶意样本库取哈希,即可在训练前拦截数据投毒。
具体案例:某大模型团队从 Common Crawl 抓取 50 亿网页,先用 sha256 对 URL 加正文分片去重,把训练集压缩 40%;再用公开毒样本哈希黑名单过滤,阻止了一批刷榜注入文本进入预训练语料。
模型权重分发与供应链安全
阶段:模型部署与 MLOps
解决的问题:开源大模型权重体积大、下载源多,传输中被篡改会导致模型后门。发布方公布 sha256 校验和,部署方下载后本地计算摘要并比对,秒级确认权重与官方一致——就像收到食材先对一对丸子的味道。
具体案例:某公司内网部署私有化大模型,MLOps 流水线在拉取权重后强制校验 sha256,并在模型 registry 里记录摘要;一次供应链投毒事件中,校验环节拦截了被替换的权重文件,避免了一次潜伏后门事故。
联邦学习中的参数验真
阶段:联邦学习聚合
解决的问题:联邦学习中各客户端上传模型更新,恶意客户端可能伪造梯度。服务端对梯度做哈希登记,聚合前校验摘要,防止中间人篡改与重放攻击。
具体案例:医疗影像联邦学习项目中,每轮各医院上传模型参数前先对参数张量计算 SHA-256 摘要并附带在消息中,服务端验真后再进入安全聚合,确保聚合结果可信。
Python 演示
import hashlibimport struct def md_pad(msg): """SHA-256 填充, 遵循 Merkle-Damgard 规范.""" m = bytearray(msg) bit_len = len(m) * 8 m.append(0x80) while len(m) % 64 != 56: m.append(0) m += struct.pack(">Q", bit_len) return bytes(m) def chain_digest(msg): """用真实 SHA-256 模拟 MD 迭代, 观察链接值传递.""" blocks = md_pad(msg) h = b"\x00" * 32 for i in range(0, len(blocks), 64): h = hashlib.sha256(h + blocks[i:i + 64]).digest() return h.hex() def diff_bits(a, b): return sum(bin(x ^ y).count("1") for x, y in zip(a, b)) def birthday_collision(bits, limit=200000): """生日攻击演示: 在截断 bits 位摘要中找碰撞.""" seen = {} mask = (1 << bits) - 1 for i in range(limit): m = str(i).encode() h = int.from_bytes(hashlib.sha256(m).digest()[:4], "big") & mask if h in seen and seen[h] != m: return seen[h], m seen[h] = m return None if __name__ == "__main__": msg = b"The secret recipe is love" flipped = bytearray(msg) flipped[0] ^= 1 print("原文摘要 :", hashlib.sha256(msg).hexdigest()) print("翻转1位 :", hashlib.sha256(bytes(flipped)).hexdigest()) print("雪崩差异 :", diff_bits(hashlib.sha256(msg).digest(), hashlib.sha256(bytes(flipped)).digest()), "/ 256") print("MD分块 :", len(md_pad(msg)) // 64, "块") print("链接链 :", chain_digest(msg)) hit = birthday_collision(16) print("16位碰撞 :", hit)
m.append(0x80)补 1 位作为消息结束标记,对应“食材切块的收尾刀”。while len(m) % 64 != 56:补 0 直到距块边界差 8 字节,留出长度字段的位置。m += struct.pack(">Q", bit_len)用大端序写入 64 位原始长度,这是防歧义的“长度支票”。h = hashlib.sha256(h + blocks[i:i + 64]).digest()上一块的摘要与当前块拼接后再次哈希,模拟链接值接力。flipped[0] ^= 1翻转第一个字节的最低比特,制造“一颗沙子的差异”。bin(x ^ y).count("1")统计两个摘要的差异比特数,验证雪崩效应。mask = (1 << bits) - 1构造截断掩码,把 256 位摘要缩到 bits 位小空间。if h in seen and seen[h] != m:命中“两食材同丸子”的碰撞判定。
常见误区
误区我经常看到密码“加密”后存进数据库,那哈希应该也是加密的一种吧?既然能加密,那管理员应该能用密钥把密码解出来呀。
正解哈希和加密是两回事。加密是“可逆变换”,有密钥就能还原;哈希是“单向压缩”,根本没有密钥这回事。回到厨房:精华丸是食材被打碎重组后的产物,物理上无法还原成牛排。SHA-256 的设计目标之一就是让反推在计算上不可行。工程上把哈希叫“摘要”而不叫“密文”,正是为了强调这一点。
为何常见:两者都输出“看不懂的乱码”,且常出现在同一张安全流程图里,初学者容易把“变换”简单归为“加密”。
误区SHA-256 有 256 位,找碰撞不就是要试 2^256 次吗?这个数字比宇宙原子还多,所以绝对安全。
正解生日悖论把碰撞成本从 2^256 砍到 2^128。就像一个班级里找两个同生日的人,不需要 365 人,23 人就够了。2^128 虽然仍不可行,但和 2^256 是数量级的差距。更要命的是算法缺陷会进一步降低成本——SHA-1 只有 160 位,实际碰撞成本被压到约 2^63,2017 年被真正攻破。安全级别永远要看“有效攻击成本”,而不是摘要位数。
为何常见:直觉把“查找”当成“遍历整个空间”,忽略了概率的杠杆效应。
误区校验和都是这样的吧,一个字节坏了,对应的那一位校验码就变一下。哈希应该也类似,改 1 位就变 1 位。
正解恰恰相反,哈希追求的是雪崩效应:输入翻转 1 位,输出应当有约一半比特翻转。SHA-256 下就是 256 位中约 128 位变化。这像往一锅汤里加一粒盐,整锅汤的“味道”都变了,而不是只影响某一粒盐所在的位置。雪崩越彻底,攻击者越难以“控制”摘要,也就越难制造碰撞。
为何常见:人们容易用 CRC 校验和的“线性”直觉去套哈希,忽略了密码学哈希刻意设计的非线性扩散。
误区都是哈希嘛,MD5 是 128 位,SHA-1 是 160 位,SHA-256 是 256 位,换个更长的就行了,反正原理一样。
正解输出长度只是参数,结构安全才是根本。MD5 和 SHA-1 与 SHA-256 同属 MD 家族,但 MD5 的碰撞成本降到 2^24 以内(2004 年已被攻破),SHA-1 也在 2017 年被 SHAttered 攻破。而 SHA-3 连结构都换成了海绵构造——它和 SHA-2 是“两种哲学”,不是“长一点的版本”。工程上,校验完整性时可以容忍弱哈希,但签名、证书等安全场景必须用 SHA-256 或 SHA-3。
为何常见:对外只呈现“一长串十六进制”,用户看不到内部结构差异,容易把哈希函数当成可互换的零件。
误区既然哈希不可逆,那我存 SHA-256(密码) 就好了,数据库泄露了攻击者也解不出密码。
正解裸哈希有两个漏洞:一是彩虹表——攻击者预先把常见密码的哈希算好存成字典,查表即得;二是速度——SHA-256 极快,GPU 每秒可算数十亿次,暴力破解 8 位纯数字密码不过是几分钟的事。正确的做法是加盐(每个用户随机盐)并选用慢哈希算法(bcrypt、scrypt、argon2),把单次验证成本拉高到毫秒级,让暴力破解的成本高到不划算。
为何常见:教程常说“只存哈希不存明文”,但没说“快哈希对攻击者也快”这个反直觉事实。
面试题
Q1. SHA-256 输出的摘要长度是多少?
- A.128 位
- B.160 位
- C.256 位← 正确答案
- D.512 位
答案:C。SHA-256 名中的 256 即摘要位数,等于 32 字节。128 位是 MD5,160 位是 SHA-1,512 位是 SHA-512。就像料理机固定吐出一颗 32 字节的精华丸,与食材大小无关。
Q2. 下列哪一项是哈希函数最核心的特性?
- A.可逆性
- B.单向性← 正确答案
- C.需要密钥
- D.输出可预测
答案:B。单向性(抗原像)是哈希区别于加密的本质:精华丸无法还原成食材。可逆的是加密而非哈希,哈希无需密钥,输出应不可预测(雪崩效应)。
Q3. 关于雪崩效应,下列说法正确的是?
- A.输入翻转 1 位,摘要恰好翻转 1 位
- B.输入翻转 1 位,摘要约一半比特翻转← 正确答案
- C.输入不变,摘要随机变化
- D.输入翻转 1 位,摘要全部变为 0
答案:B。雪崩效应要求输入微小变化导致输出约一半比特翻转,SHA-256 下约 128 位变化。这保证攻击者无法通过控制输入来预测或碰撞摘要。
Q4. 在 Merkle-Damgard 结构中,链接变量 h_i 的作用是?
- A.记录消息总长度
- B.把上一消息块的摘要传给下一块,形成链式依赖← 正确答案
- C.充当加密密钥
- D.填充随机噪声
答案:B。链接值像接力棒,h_i = f(h_{i-1}, M_i),把前面所有块的信息层层传递。消息长度由填充阶段的 64 位字段记录,密钥与哈希无关。
Q5. 以下哪些是 SHA-3 海绵构造的特点?
- A.分为吸收与挤压两个阶段← 正确答案
- B.核心是 Keccak-f 置换← 正确答案
- C.采用 Merkle-Damgard 迭代
- D.天然抵抗长度扩展攻击← 正确答案
答案:ABD。海绵构造采用吸收-挤压两阶段,核心置换 Keccak-f,且天然免疫 MD 结构的长度扩展攻击。选项 C 是 SHA-1/SHA-2 家族的结构,与 SHA-3 相反。
Q6. 对 SHA-256 实施生日攻击,期望的碰撞尝试次数约为?
- A.2^64
- B.2^128← 正确答案
- C.2^256
- D.2^512
答案:B。生日悖论把碰撞成本压到 2^(n/2),n=256 时为 2^128。2^64 是 SHA-1 时代的碰撞界,2^256 是抗原像的暴力成本。
Q7. 关于长度扩展攻击,下列说法正确的是?
- A.可利用 SHA-256 等 MD 结构哈希← 正确答案
- B.需要知道原消息摘要和消息长度← 正确答案
- C.SHA-3 海绵构造天然免疫该攻击← 正确答案
- D.需要知道原消息的完整内容
答案:ABC。长度扩展攻击利用 MD 结构“末状态即摘要”的特性,已知 H(m) 和长度即可伪造 H(m ‖ padding ‖ extra),无需知道 m;海绵构造输出与挤压次数绑定,免疫此攻击。D 错误。
Q8. 2017 年 SHA-1 被正式宣布退役(SHAttered)的直接原因是?
- A.输出长度仅 96 位
- B.研究者找到了真实的碰撞样本← 正确答案
- C.私钥被大规模泄露
- D.量子计算机已可破解
答案:B。Google 与 CWI 联合发布了两个内容不同但 SHA-1 摘要相同的 PDF 文件,碰撞成本被压到约 2^63。这证明“同族缩短版”并不安全,推动浏览器全面弃用 SHA-1 证书。
Q9. 工程上存储用户口令,推荐的做法是?
- A.明文存储到数据库
- B.直接存 SHA-256(口令)
- C.加盐并使用 bcrypt 等慢哈希← 正确答案
- D.用固定密钥加密口令
答案:C。慢哈希加盐能同时抵御彩虹表和 GPU 暴力破解。裸 SHA-256 太快、无盐易被预计算,固定密钥加密一旦泄露全部还原,明文存储则完全不可接受。
Q10. 关于 Keccak-f 置换,正确的说法有?
- A.状态总大小为 1600 位← 正确答案
- B.状态排成 5×5 的 lane 矩阵← 正确答案
- C.每一轮包含 θ、ρ、π、χ、ι 五种运算← 正确答案
- D.χ 是线性运算
答案:ABC。Keccak-f 在 1600 位状态(25 个 64 位 lane)上迭代 24 轮,每轮五种运算;其中 χ 是唯一的非线性步骤,负责提供抗攻击的关键混淆。D 错误。