Java 侧用 AES/CBC/PKCS5Padding 加密,Node 用 crypto 默认的 PKCS7 解密,前 16 字节正常后面全是乱码,进程报 bad decrypt,同一段密文 Java 自己能解。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,PKCS5 和 PKCS7 在 AES 的 16 字节块下填充规则一致,问题不在这里。真正的差异是 IV 编码和密钥长度,Node 把 hex 当 utf8 读,密钥从 32 字节变成 64 字节。封装时没有约定编码。
碰到「跨语言解密失败」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。别只看报错的最后一行,往上看几行,真正的起因通常在上面。
openssl enc -aes-256-cbc -d -K 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -iv 0102030405060708090a0b0c0d0e0f10 -in java.enc -out java.txt node decrypt.js java.enc cmp java.txt node.txt
同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
具体做法是,密钥和 IV 统一用 Base64 传输 两边都按 Base64 解码;明确算法串 aes-256-cbc 和填充方式 写进接口文档;用同一组测试向量在两种语言各跑一遍;把 Node 的解密结果和 Java 的明文逐字节比对。
最后用这个标准收尾,两种语言解出的明文逐字节一致 cmp 返回 0 不再出现 bad decrypt。
