2. 密码学基础回顾

密码算法选型的第一步,不是比较性能数字,而是把六类基础原语各自“解决什么问题、不解决什么问题”分清楚。它们常被混在一起讨论,但在安全目标上分工明确:对称加密提供机密性,非对称加密在密钥分发困难时提供机密性或密钥封装,哈希函数提供数据完整性指纹,消息认证码(MAC)在共享密钥前提下提供完整性与来源认证,数字签名在公钥前提下提供不可否认的完整性与来源认证,密钥交换则负责让双方在不安全信道上协商出共享秘密。选型错误往往不是算法被攻破,而是用错了原语去承担它本不负责的目标。

对称加密:用同一把密钥保护机密性

对称加密使用同一密钥完成加密与解密,典型代表是 AES。它把明文按分组处理,AES 分组固定为 128 位,密钥长度可选 128、192、256 位。分组密码本身只解决“一个分组怎么变换”,实际使用必须配合工作模式。常见模式中,ECB 对相同明文分组产生相同密文,会泄露数据结构,不应使用;CBC 需要随机且不可预测的 IV,且只提供机密性,不提供完整性;CTR 把分组密码变成流密码,允许并行,但 IV/计数器绝不能重复;GCM 属于 AEAD(带关联数据的认证加密),一次同时给出机密性与完整性,是现代协议的首选。

以 AES-256-GCM 为例,一次加密需要:256 位密钥、96 位随机 nonce、明文 P、可选的关联数据 AAD。输出为密文 C 和 128 位认证标签 T。解密时若标签校验失败,必须整体拒绝,不能返回任何明文片段。这里的关键判断依据是:nonce 在同一密钥下重复使用会直接破坏 GCM 的安全性,因此工程上常用计数器或随机数加持久化防重。对称加密的优点是速度快、适合大数据量;缺点是密钥必须双方共享,密钥数量随通信方增长呈平方级膨胀,且无法天然解决“对方是谁”的问题。

非对称加密:公钥公开、私钥保密

非对称加密使用一对数学关联的密钥:公钥可公开,私钥必须保密。RSA 基于大整数分解困难,常见密钥长度 2048 或 3072 位;ECC 基于椭圆曲线离散对数困难,256 位曲线(如 P-256)即可提供约 128 位安全强度。非对称加密解决了密钥分发问题,但运算慢、能加密的数据长度受限。RSA-OAEP 一次能加密的明文长度约为“模长减去两倍哈希长度再减 2”,2048 位密钥配 SHA-256 时约 190 字节,因此它通常只用来加密一个对称密钥,而不是直接加密业务数据。

这里要区分两个容易混淆的目标:非对称加密提供的是机密性,任何人都能用公钥加密,只有私钥持有者能解密;而数字签名方向相反,私钥签名、公钥验证,提供的是完整性与来源认证。把“用私钥加密”当作签名是过时且不安全的说法,现代签名必须使用带哈希与填充的标准方案,如 RSA-PSS、ECDSA、Ed25519。

哈希函数:把任意数据压缩成固定长度指纹

哈希函数把任意长度输入映射为固定长度输出,如 SHA-256 输出 256 位。它需要满足三个性质:抗原像性(给定摘要难反推输入)、抗第二原像性(给定输入难找另一输入得到相同摘要)、抗碰撞性(难找任意两个不同输入得到相同摘要)。哈希本身不提供机密性,也不提供来源认证——任何人都能对同一数据算出相同摘要。它最典型的用途是完整性校验、口令存储(配合盐与慢哈希如 Argon2、scrypt、PBKDF2)以及作为签名和 MAC 的内部构件。

需要特别提醒:MD5 与 SHA-1 已被证明存在实用碰撞攻击,不能用于签名、证书或任何安全场景;SHA-256、SHA-384、SHA-512 以及 SHA-3 系列目前仍属安全选择。哈希输出长度直接决定碰撞难度,128 位输出在生日攻击下只有约 64 位安全强度,因此安全场景应优先选择 256 位及以上输出。

消息认证码与数字签名:两种“认证”的分界

MAC 使用共享密钥,对消息计算认证标签,验证方用同一密钥重算并比对。HMAC-SHA256 是最常见的构造,输出 256 位标签。它能同时保证完整性和来源认证,但前提是双方共享同一密钥,因此无法向第三方证明消息来自哪一方——因为验证方自己也能生成同样的标签。数字签名则用私钥签名、公钥验证,任何持有公钥的人都能验证,签名者无法抵赖,因此具备不可否认性。选型判断很简单:双方共享密钥、只需彼此确认,用 MAC;需要向第三方举证、需要不可否认,用数字签名。

密钥交换:在不安全信道上协商共享秘密

密钥交换解决“双方从未见过面,如何在不安全信道上得到同一把密钥”。Diffie-Hellman 利用离散对数:双方各自选私钥 a、b,公开 A=g^a mod p、B=g^b mod p,各自计算 B^a 与 A^b,得到相同的 g^(ab) mod p。攻击者即使截获 A、B,也难算出共享秘密。ECDH 把这一思想搬到椭圆曲线上,用更短密钥达到同等强度。但裸 DH/ECDH 不认证身份,会遭受中间人攻击,因此实际使用中必须配合签名或证书,形成 ECDHE 等临时密钥交换,并具备前向保密:即使长期私钥泄露,历史会话密钥也不受影响。

六类密码原语:输入、密钥关系与安全目标 对称加密(AES-GCM) 同一密钥 K 加解密 输入:明文 + nonce + AAD 输出:密文 + 认证标签 目标:机密性(+完整性) 非对称加密(RSA-OAEP / ECIES) 公钥加密,私钥解密 典型用途:封装对称密钥 RSA-2048 单次约 190 字节 目标:机密性 / 密钥分发 哈希函数(SHA-256) 任意长度 → 固定 256 位摘要 抗原像 / 抗第二原像 / 抗碰撞 无密钥,不认证来源 目标:完整性指纹 哈希是 MAC 与签名的内部构件 消息认证码(HMAC-SHA256) 共享密钥 K + 消息 → 标签 验证方用同一 K 重算比对 验证方也能生成 → 不可抵赖性弱 目标:完整性 + 来源认证 数字签名(ECDSA / Ed25519) 私钥签名,公钥验证 任何持公钥者可独立验证 签名者无法否认 → 不可抵赖 目标:完整性 + 不可否认 密钥交换(ECDHE) 双方公开 A、B,各自算出同一共享秘密 裸 DH 不认证身份,需签名/证书防中间人 目标:安全协商共享密钥 协商出的密钥供对称加密与 MAC 使用

把六类原语串成一条实际链路

真实协议很少只用一种原语。以一次 TLS 1.3 握手为例:客户端与服务器先通过 ECDHE 协商出共享秘密,用证书中的公钥验证服务器签名,确认对方身份;随后用 HKDF(基于 HMAC 的密钥派生)从共享秘密派生出会话密钥;应用数据阶段使用 AES-256-GCM 或 ChaCha20-Poly1305 加密并认证。这里每一层都各司其职:ECDHE 负责密钥协商与前向保密,签名负责身份认证,HKDF 负责密钥派生,AEAD 负责数据机密性与完整性。任何一层被替换成不合适的原语,整条链路的安全目标都会出现缺口。

选型速记:要保密且双方共享密钥 → 对称加密;要保密但无共享密钥 → 非对称加密封装密钥;只要指纹 → 哈希;共享密钥下要认证 → MAC;需要向第三方证明 → 数字签名;要在不安全信道协商密钥 → DH/ECDH 并配合认证。
常见误区:用 MD5/SHA-1 做签名或证书;ECB 模式加密业务数据;GCM 下重复使用 nonce;把裸 DH 当作已认证密钥交换;用“私钥加密”代替标准签名方案。这些都不是算法强度问题,而是原语与安全目标错配。
原语密钥关系核心安全目标典型算法不负责
对称加密双方共享同一密钥机密性AES-GCM、ChaCha20-Poly1305来源认证、不可否认
非对称加密公钥加密、私钥解密机密性、密钥分发RSA-OAEP、ECIES大数据量直接加密
哈希函数无密钥完整性指纹SHA-256、SHA-3机密性、来源认证
消息认证码双方共享密钥完整性 + 来源认证HMAC-SHA256、CMAC第三方不可否认
数字签名私钥签名、公钥验证完整性 + 不可否认ECDSA、Ed25519、RSA-PSS数据机密性
密钥交换各自私钥、公开参数协商共享秘密ECDHE、X25519身份认证(需配合签名)