按合规要求把 KMS 主密钥轮换到 v2,上线后查询三个月前的订单,解密手机号时抛 InvalidCiphertextException,同一批数据在轮换前能正常解。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
aws kms list-aliases --query 'Aliases[?AliasName==`alias/order-pii`]' aws kms decrypt --ciphertext-blob fileb://cipher.bin --key-id alias/order-pii
旧数据是用 v1 密钥加密的,密文里没有记录密钥版本,解密时统一用了当前版本。KMS 轮换只换了主密钥,历史密文不会自动重加密。代码把密钥别名当成固定值,取到的永远是最新版本。这一点先确认清楚,后面就不用反复试。
「密钥轮换解密失败」这类改动最怕改一半,回滚脚本先准备好,再动生产。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
具体做法是,密文头部补一个字节的密钥版本号 写入时一起存;解密时先读版本 再按版本取对应的 key id;写一个后台任务把存量数据逐步重加密到 v2;拿一条三个月前的订单验证能解出原号码。
改完照着核一遍,旧订单解密返回明文手机号 日志里不再出现 InvalidCiphertextException。
