2. 加密算法选型与数据对象映射

静态数据加密架构设计的第一步,不是选一个"最强的算法",而是把数据对象与算法族建立正确的映射关系。对称加密、非对称加密、哈希与KDF(密钥派生函数)解决的是四类不同的问题:机密性、密钥交换与身份、完整性校验、密钥生成与口令加固。选型错误的典型后果是:用非对称加密保护大字段导致性能崩溃,用哈希"加密"敏感数据导致无法还原,或用裸哈希存储口令导致撞库风险。本节先厘清四类算法的适用边界,再给出按数据类型选型的可执行方法。

四类算法的能力边界

对称加密(AES-256-GCM、AES-256-CBC、ChaCha20-Poly1305、SM4)用同一密钥加解密,吞吐量高、适合批量数据。它的边界是:密钥必须安全分发与保存,且不提供身份证明。静态数据加密中,对称加密是数据面的主力——数据库字段、文件、对象存储、备份介质都由它保护。推荐优先选择带认证的AEAD模式(GCM、ChaCha20-Poly1305、SM4-GCM),因为它同时提供机密性与完整性,避免密文被篡改后解密出错误明文。

非对称加密(RSA-2048/3072、ECC P-256、SM2)用公钥加密、私钥解密,或私钥签名、公钥验签。它的边界是:运算慢、密文膨胀、单次可加密的数据量受限(RSA-2048 配合 OAEP 约 190 字节)。因此它不用于加密业务数据本身,而是用于保护对称密钥(信封加密)、数字签名与身份认证。在静态加密架构中,非对称加密通常出现在密钥管理层:KMS 的主密钥、TLS 证书、签名验签。

哈希(SHA-256、SHA-3、SM3)是单向压缩,不可逆,用于完整性校验、指纹、去重标识、签名摘要。它的边界是:不能用于需要还原的机密性保护;裸哈希不能用于口令存储。哈希在静态加密中承担"校验与标识"角色,例如文件完整性清单、密文指纹、数据去重键。

KDF(PBKDF2、bcrypt、scrypt、Argon2、HKDF)从口令或主密钥派生出密钥材料。它的边界是:KDF 本身不加密数据,只负责"把弱输入变成强密钥"或"从一个主密钥派生多个用途密钥"。口令存储应使用 Argon2id 或 bcrypt 这类慢哈希;从主密钥派生数据密钥应使用 HKDF 这类快速、可指定上下文信息的 KDF。

数据对象 → 算法族映射与密钥流 数据对象 数据库字段 / 行 PII、卡号、手机号 文件 / 对象存储 附件、影像、备份 口令 / 凭据 登录口令、PIN 数据密钥 / 主密钥 DEK、KEK 完整性清单 / 指纹 去重键、校验值 签名 / 身份 证书、验签 算法族 对称加密 AES-256-GCM / ChaCha20 SM4-GCM 高吞吐 · 机密性+完整性 非对称加密 RSA-OAEP / ECC / SM2 密钥封装 · 签名 慢 · 数据量受限 哈希 SHA-256 / SHA-3 / SM3 单向 · 定长摘要 校验 · 指纹 · 去重 KDF Argon2id / bcrypt / HKDF 口令加固 · 密钥派生 密钥与信任流 主密钥 KEK(KMS/HSM) 非对称或对称根密钥 数据密钥 DEK AES-256,按对象/租户 信封加密 KEK 加密 DEK 后随密文存储 完整性校验 GCM Tag / HMAC / 哈希清单 轮换与审计 DEK 轮换、KEK 版本、日志

按数据类型选型的判断方法

选型可以按"是否需要还原"和"数据规模"两个维度快速判断。需要还原且数据量大,选对称加密;需要还原但数据量小且涉及跨信任域,选非对称加密保护密钥、对称加密保护数据;不需要还原,选哈希;输入是口令或需要派生多个密钥,选 KDF。下面给出一个可直接对照的选型表。

数据对象推荐算法关键参数示例不推荐做法
数据库敏感字段AES-256-GCM96位随机IV,128位Tag,字段级DEKECB模式、固定IV
大文件/对象存储AES-256-GCM 或 ChaCha20-Poly1305分块加密,每块独立IV,块序号入AAD整文件一次性读入内存加密
登录口令Argon2id内存64MB、迭代3次、并行度4、16字节盐MD5/SHA-1裸哈希、可逆加密
数据密钥DEKRSA-3072-OAEP 或 AES-256-KWKEK保护DEK,密文随数据存储DEK明文落盘、硬编码在代码中
完整性清单SHA-256 或 HMAC-SHA-256逐文件摘要,HMAC密钥独立管理用CRC32做安全校验
主密钥派生HKDF-SHA-256salt+info区分用途,输出32字节直接截断主密钥当DEK

一个可执行的信封加密示例

以"用户表手机号字段加密"为例,说明参数如何落地。假设使用 AES-256-GCM,每个租户一个DEK,DEK由KMS中的KEK通过AES-256-KW封装。加密时生成12字节随机IV,将"租户ID+字段名+版本号"作为AAD(附加认证数据),防止密文被跨字段搬移。伪代码如下:

// 示例参数,非实测结果
dek = kms.unwrap(tenantId)              // 取出租户DEK
iv  = randomBytes(12)                   // 96位随机IV
aad = utf8(tenantId + "|phone|v1")      // 绑定上下文
ct, tag = AES_256_GCM_encrypt(dek, iv, aad, plaintext)
stored = base64(iv || tag || ct)        // 存储格式:IV+Tag+密文
// 解密时用相同aad校验,Tag不匹配则拒绝返回明文

判断结果是否正确的依据有三条:一是同一明文两次加密得到的密文不同(IV随机);二是篡改密文任意一位后解密失败(Tag校验);三是把A字段密文放到B字段解密失败(AAD绑定)。这三条同时成立,说明字段级加密的机密性与完整性都生效。

选型时优先使用AEAD模式(GCM、ChaCha20-Poly1305、SM4-GCM),它把机密性和完整性一次解决,避免"先加密再单独HMAC"带来的密钥管理和顺序错误。
不要用哈希"加密"需要还原的数据,也不要用对称加密存储口令。口令必须用Argon2id、bcrypt或scrypt这类慢哈希,并加盐;哈希不可逆,加密可逆,两者混用会造成无法恢复或可被批量破解的后果。

常见选型误区与纠正

  • 误区一:算法越新越好。纠正:先看合规与生态支持。国密场景选SM4-GCM、SM3、SM2;通用场景AES-256-GCM与ChaCha20-Poly1305都是成熟选择。
  • 误区二:一个密钥加密所有数据。纠正:按租户、按对象、按用途分离DEK,降低单点泄露影响面,也便于轮换。
  • 误区三:IV可以固定或复用。纠正:GCM下IV复用会直接破坏机密性与完整性,必须每次加密随机生成或使用严格递增计数器。
  • 误区四:KDF只是"哈希一下"。纠正:口令用慢哈希并调参,密钥派生用HKDF并传入用途信息,两者目标不同,不能互换。