加密
将数据转换为不可读格式的技术。只有持有解密密钥的人才能恢复原始数据。
加密是把明文 (plaintext) 转换成密文、只让持有正确解密密钥的一方能读回原始数据的技术。它对于防范互联网上的通信窃听、数据库的未授权访问、设备被盗等各种威胁不可或缺,构成了现代信息安全的根基。
加密方式大致分为两类。对称密钥加密 (共享密钥加密) 用同一个密钥进行加密和解密,代表是 AES (Advanced Encryption Standard)。它处理速度快,适合加密大量数据,但密钥如何安全地交到对方手里是个难题。公钥加密 (非对称密钥加密) 使用加密用的公钥与解密用的私钥这一对密钥,代表是 RSA 和椭圆曲线加密 (ECC)。它解决了密钥配送问题,但处理速度比对称密钥加密慢。
实际通信中使用的是把两种方式组合起来的混合加密。HTTPS 通信的 TLS 协议先用公钥加密安全地交换对称密钥,之后的通信则用高速的对称密钥加密来进行。AES-256 是 2026 年时点上使用最广泛的对称密钥加密之一,密钥长度为 256 位,一般认为面对穷举攻击实际上无法破解。
加密与哈希是容易混淆的概念。加密是只要有解密密钥就能还原成原始数据的"可逆变换",而哈希是无法还原成原始数据的"不可逆变换"。密码的保存要用哈希 (bcrypt、Argon2 等),通信数据的保护要用加密,这才是正确的分工。如果用加密来保存密码,一旦密钥泄露,所有密码都有被还原出来的风险。从字符计数的角度看,bcrypt 把输入截断到 72 个字节的规格是个陷阱。UTF-8 下的日语 1 个字符占 3 个字节,因此日语的密码短语超过 24 个字符的部分不会反映到哈希里。要设计成允许长密码短语,就得选 Argon2 这类对输入长度限制宽松的算法,或者事先用 SHA-256 等折叠成固定长度再传进去。
作为用途受限的方式,还有端到端加密 (E2EE)。它只在发送方与接收方之间可以解密,连服务提供商也读不到内容,Signal 和 WhatsApp 等即时通讯应用采用了这一机制。另外,为量子计算机的发展做准备的抗量子加密 (后量子密码) 的标准化也在推进,NIST 在 2024 年 8 月公开了 FIPS 203 (ML-KEM)、FIPS 204 (ML-DSA)、FIPS 205 (SLH-DSA) 这 3 项。它们是以逐步替换现有的 RSA 和椭圆曲线加密为前提的规格,而密钥和签名的尺寸比以往更大,这一点会成为迁移时设计上的议题。
从字符计数的角度看,加密后的数据通常比原始数据更长。AES 的分组长度是 16 个字节,所以 CBC 模式的填充会增加 1 到 16 个字节,此外常见的实现还会把 16 个字节的初始化向量 (IV) 附在密文开头。再配合 Base64 编码,就会在此基础上增加约 33%。举例来说,把 ASCII 的 100 个字符 (100 个字节) 用 AES-256-CBC 加密,密文是 112 个字节,Base64 后是 152 个字符,含 IV 则是 172 个字符。同样是 100 个字符,如果是日语,在 UTF-8 下有 300 个字节,于是密文 304 个字节、Base64 后 408 个字符,含 IV 会膨胀到 428 个字符。像 AES-GCM 这类带认证的加密还要再加上 16 个字节的认证标签。
因此,API 的请求大小限制和数据库的列大小,需要从明文的字节数而不是"字符数"来倒推。可以作为估算的做法是:"把明文字节数向上取整到 16 的倍数,加上 IV 与标签的份,再乘 4 / 3 并向上取整到 4 的倍数",这样求出所需的位数。在处理日语的列上,相对明文的字符数留出 4 倍多一点的余量,就不容易出问题。