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 等临时密钥交换,并具备前向保密:即使长期私钥泄露,历史会话密钥也不受影响。
把六类原语串成一条实际链路
真实协议很少只用一种原语。以一次 TLS 1.3 握手为例:客户端与服务器先通过 ECDHE 协商出共享秘密,用证书中的公钥验证服务器签名,确认对方身份;随后用 HKDF(基于 HMAC 的密钥派生)从共享秘密派生出会话密钥;应用数据阶段使用 AES-256-GCM 或 ChaCha20-Poly1305 加密并认证。这里每一层都各司其职:ECDHE 负责密钥协商与前向保密,签名负责身份认证,HKDF 负责密钥派生,AEAD 负责数据机密性与完整性。任何一层被替换成不合适的原语,整条链路的安全目标都会出现缺口。
| 原语 | 密钥关系 | 核心安全目标 | 典型算法 | 不负责 |
|---|---|---|---|---|
| 对称加密 | 双方共享同一密钥 | 机密性 | AES-GCM、ChaCha20-Poly1305 | 来源认证、不可否认 |
| 非对称加密 | 公钥加密、私钥解密 | 机密性、密钥分发 | RSA-OAEP、ECIES | 大数据量直接加密 |
| 哈希函数 | 无密钥 | 完整性指纹 | SHA-256、SHA-3 | 机密性、来源认证 |
| 消息认证码 | 双方共享密钥 | 完整性 + 来源认证 | HMAC-SHA256、CMAC | 第三方不可否认 |
| 数字签名 | 私钥签名、公钥验证 | 完整性 + 不可否认 | ECDSA、Ed25519、RSA-PSS | 数据机密性 |
| 密钥交换 | 各自私钥、公开参数 | 协商共享秘密 | ECDHE、X25519 | 身份认证(需配合签名) |