AES密钥包装(RFC3394/5649)解包无法还原原密钥问题
AES密钥包装与解包问题及修复方案
密钥包装步骤
- 将待包装密钥转换为
byte[] - 执行AES包装操作:
- 获取Cipher实例:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - 生成
IvParameterSpec实例 - 基于包装密钥创建SecretKey对象:
SecretKey secretKey = new SecretKeySpec(wrapperKey, "AES"); - 初始化为加密模式:
cipher.init(Cipher.WRAP_MODE, secretKey, iv); - 执行包装:
byte[] wrappedKey = cipher.wrap(new SecretKeySpec(keyToWrap, "AES")); - 返回包装后的密钥字节数组
- 获取Cipher实例:
密钥解包步骤
- 将包装后的密钥转换为
byte[] - 执行AES解包操作:
- 获取Cipher实例:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - 提取IV(固定16字节长度)
- 基于包装密钥创建SecretKey对象:
SecretKey secretKey = new SecretKeySpec(wrapperKey, "AES"); - 初始化为解包模式:
cipher.init(Cipher.UNWRAP_MODE, secretKey , iv); - 执行解包:
Key unwrappedKey = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);
- 获取Cipher实例:
问题现象
按上述流程解包时无法还原原始密钥,差异出现在字节数组的前16字节(与IV长度一致)。使用的加密依赖为SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General aliases: [Rijndael],对比输出可见:原始密钥与解包后密钥的前16字节不匹配,但后续字节完全一致。
修复方案
完成密钥包装后,将IV字节数组前置到包装后的密钥字节数组中,确保解包时能获取到对应的正确IV。代码实现如下:
byte[] wrappedKey = cipher.wrap(new SecretKeySpec(keyToWrap, "AES")); // 将IV前置到包装后的密钥中 byte[] result = new byte[ivBytes.length + wrappedKey.length]; System.arraycopy(ivBytes, 0, result, 0, ivBytes.length); System.arraycopy(wrappedKey, 0, result, ivBytes.length, wrappedKey.length);
内容的提问来源于stack exchange,提问作者qwerty
相关产品推荐
相关产品推荐

