1.3 三块积木的拼法与常见错拼


1.3 三块积木的拼法与常见错拼

本节摘要:对称加密、非对称加密、哈希是几乎所有密码协议仅有的三种结构件。本节讲清三者的能力边界与开销量级,解释"非对称换钥匙、对称搬货物"这条工程铁律的由来,然后逐个拆解三类经典错拼——该签名的只加密、该绑身份的只绑密钥、把哈希当加密用。读完你能看着一份协议的密码学调用清单,判断它拼得对不对。

先补三行数学:模运算够用了

非对称密码的直觉全部建立在模运算上,三行补齐。"17 mod 12"读作"17 除以 12 的余数",结果是 5;时钟就是模 12 的世界,13 点就是 1 点。模幂运算是"先算幂再取余",例如 3 的 4 次方等于 81,模 13 得 3。它有个要命的特性:从 3 和 4 算出 3 很容易,但从 3 和 3 反推那个 4(离散对数)在数足够大时没有任何已知的有效算法。非对称密码的全部安全感都压在"正向容易、反向困难"这类不对称上。

还有一条运算规则值得记住:异或。两个比特相同得 0、不同得 1,它满足"自己异或自己等于零、任何数异或零不变"。这条性质让"密钥异或明文得到密文,密文异或同一密钥还原明文"成立——对称加密最朴素的形态,也是后面多处错误拼装的病灶所在。

三块积木的能力边界

对称加密(如 AES、ChaCha20):一把密钥既加密又解密,速度极快(硬件指令加持下每秒可处理数 GB),但有一个致命的组织学问题——双方必须先持有同一把密钥,而"如何在不安全信道里把这把钥匙送过去"正是它自己解决不了的问题。非对称加密(如 RSA)与密钥协商(如 Diffie-Hellman):一对密钥,公钥可公开、私钥自己守,从数学上解决了"素未谋面的双方建立共享秘密"这个几百年无解的问题;代价是运算比对称慢两三个数量级,且单次能安全承载的数据量小。哈希(如 SHA-256):单向压缩,任意输入得到固定长度"指纹",不可逆、改一个比特指纹面目全非;它不加密任何东西——没有密钥,谁都能算,这是它和加密最本质的区别。

由此得出那条工程铁律:非对称换钥匙,对称搬货物。真实会话里,非对称运算只在开场用一两次,协商出临时对称密钥;之后所有流量都用对称密钥加密。你可以粗算一笔账:非对称操作如果按毫秒计,对称操作按纳秒计,一次网页会话传几百 KB 数据,全用非对称会让握手开销放大上万倍——TLS 每条连接都做完整握手仍能支撑整个互联网,靠的就是"贵的东西只用在刀刃上"。

# 用小数字演示 Diffie-Hellman 密钥协商的机制(教学演示,真实参数需 2048 位以上) p = 23 # 公开的大素数(演示用小素数) g = 5 # 公开的生成元 # A 选私密随机数 a,计算公开值 A_pub = g^a mod p a = 6 A_pub = pow(g, a, p) # 5^6 mod 23 = 8 # B 选私密随机数 b,计算公开值 B_pub = g^b mod p b = 15 B_pub = pow(g, b, p) # 5^15 mod 23 = 19 # 双方交换公开值后,各自计算共享秘密 sA = pow(B_pub, a, p) # 19^6 mod 23 = 2 sB = pow(A_pub, b, p) # 8^15 mod 23 = 2 两者必然相等 print(A_pub, B_pub, sA, sB) # 8 19 2 2 —— 数学保证 sA == sB # 偷听者只拿到 p、g、8、19,求共享值 2 需解离散对数——p 足够大时不可行

注意这份演示代码里藏着一个真问题:偷听者看到 8 和 19,只要离散对数难题不可解就拿不到 2——但坐在中间的敌手不需要解数学,他可以分别跟 A、B 各做一次协商。这正是中间人攻击,它不是数学漏洞而是协议漏洞,解药是给协商过程加上认证(4.1 节 TLS 1.3 的做法)。

三类经典错拼与病根

第一类:该签名的只加密。"我用你的公钥加密了数据,所以只有你能看、也就是你发的"——前半句对,后半句非欧。公钥人人可得,敌手也能拿你的公钥加密一段伪造数据发给你。加密提供机密性,不提供来源证明;要来源证明必须用发送方私钥签名。病根是把 1.2 节的两个属性混为一谈。修法:来源敏感的数据走"签名 + 加密"或签密构造。

第二类:该绑身份的只绑密钥。协议验证了"这条消息出自持有某私钥的人",却没有验证"这个私钥对应的就是我想对话的那个人"——密钥与身份的绑定被跳过了。绑定靠什么?证书体系、预共享的密钥指纹、透明日志,形式各异,但没有绑定动作的认证是空转。心脏出血之外多数著名中间人事故(包括后面要复盘的案例)都有这个成分。病根:把"认证了密钥"当成"认证了身份"。修法:在安全目标里显式写出"密钥 K 属于身份 X"这条绑定命题,并在协议中用可验证的途径落实它。

第三类:把哈希当加密用。"密码存库前做个 SHA-256 就安全了"——哈希无密钥、可预计算,攻击者拿到库后对常见密码字典批量算哈希比对即可。病根是混淆了"不可逆"与"不可猜":哈希对任意输入都不可逆,但弱输入(常见密码)可以被穷举。修法:口令存储用专门的慢哈希并加盐(如 Argon2、bcrypt 这类口令哈希方案),让每次猜测的计算成本高到穷举不划算。这个错拼的流行度长盛不衰,因为它"看起来"达到了目的——直到库泄露的那天。

💡 一个判断直觉:看到任何一份协议或设计文档,先数它做了几次加密、几次签名、几次哈希,然后对每一次问"它在为哪个属性服务、绑定了哪个身份"。三次追问下来,大部分错拼会自己现形。

回答上节留下的练习

现在可以收 1.1 节那个变式的尾了:把 NS 三步协议改成对称密钥版本。用共享密钥 Kab 替换公钥运算后,消息 1 变成用 Kab 加密——于是 B 一解密就能确认"消息出自与我有共享密钥的一方",发起方认证反而变强了;但代价是协议只能用于"早已共享密钥的两方",失去了公钥体制"素未谋面也能建立信任"的核心价值。历史正是沿着这两条支路演化的:对称路径长成了 Kerberos 这类基于可信第三方的体系,公钥路径长成了证书体系——两条路在今天的 TLS 里同时在场(证书认证身份,握手协商对称会话密钥)。第 4 章手推 TLS 1.3 时你会亲眼看到这次汇合。

积木速查表与选型直觉

三块积木讲完,值得收成一张速查表,评审时按行过:

积木 提供什么 不提供什么 开销 典型位置
对称加密 机密性(快、大流量) 来源证明、无密钥时的任何保护 纳秒级 会话数据本体
非对称(加密/协商) 建立共享秘密、身份锚点 大流量加密(太贵太慢) 毫秒级 握手开场一两次
哈希 指纹、派生、绑定 机密性(无密钥可逆算) 微秒级 派生密钥、完整性、承诺

选型直觉一句话:先问"要哪个属性",再问"数据量多大",两个答案相交处就是要用的积木——属性对应能力边界,数据量对应开销边界。凡是想用哈希"藏住"什么东西的念头都值得多想一秒:哈希藏不住内容,只藏得住"哪一个是它"。

本节要点回顾

  • 模运算不对称性:模幂正向容易、离散对数反向困难,非对称密码的安全感全部压在"正向容易反向难"上。
  • 铁律:非对称换钥匙、对称搬货物;开销量级差两三个数量级,决定了真实协议的分层结构。
  • 错拼一:加密只给机密性,来源证明必须签名,两者不可互相替代。
  • 错拼二:认证密钥不等于认证身份,"密钥 K 属于身份 X"的绑定必须显式落实。
  • 错拼三:哈希无密钥不可预抗穷举,口令存储必须用加盐的慢哈希方案。

第 1 章到此把道具间收拾完毕。下一章我们请主角登场——把敌手的能力一条条写实:他偷听到什么、能改什么、不能做什么。没有这份能力清单,后面所有推演都无从谈起。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U