openssl enc -aes-256-cbc -K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -iv 00000000000000000000000000000000 -in a.txt -out a.enc
openssl enc -aes-256-cbc -K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -iv 00000000000000000000000000000000 -in a.txt -out b.enc
cmp a.enc b.enc

抽查加密列发现两个不同用户的手机号密文前 16 字节完全相同,只有后半段不同,代码里 IV 是 new byte[16] 全零,一直没换过。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,CBC 模式要求每次加密使用随机 IV,固定 IV 会让相同明文产生相同密文前缀。攻击者拿不到密钥也能通过比对密文判断两个号码是否相同。全零 IV 是最容易被扫出来的一种写法。

「固定 IV 复用」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

处理上按这个顺序:每次加密生成 16 字节随机 IV 用 SecureRandom;IV 不需要保密 和密文拼在一起存储 前 16 字节就是 IV;解密时先切出 IV 再解剩余部分;用同一个手机号加密两次 比较两段密文。

改完只确认一件事:同一手机号加密两次密文不同 两个用户相同号码的密文前缀不再一致。

作者 9823189