当我在Android中运行此代码时,它不会产生任何错误,但是当我在标准Java程序中运行它时会产生异常:java.security.InvalidKeyException:非法的密钥大小。
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(CHUNK_ENCRYPTION_KEY.getBytes(), 0, 32, "AES");
IvParameterSpec initVector = new IvParameterSpec(AES_INITIALIZATION_VECTOR.getBytes(), 0 , 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, initVector);
CHUNK_ENCRYPTION_KEY是一个32字节的密钥,硬编码到程序中。 AES_INITIALIZATION_VECTOR是一个16字节的硬编码初始化向量。
有谁知道为什么它可以在Android上运行而不在桌面上运行?
答案 0 :(得分:24)
在默认桌面JVM安装(使用Sun / Oracle的JRE或JDK)上,AES限制为128位密钥大小。这是加密软件的进出口法律的残余。要解锁较大的AES密钥大小,您需要下载并应用“JCE Unlimited Strength Jurisdiction Policy Files”(请参阅this page的底部)。
密钥大小限制由Cipher
类中的代码强制执行。更改加密提供程序(例如更改为Bouncy Castle或IAIK提供商之一)不会让您绕过此限制。
在不相关的说明中,您不希望在getBytes()
上使用原始String
方法,因为结果取决于当前的区域设置(并非每个人都使用UTF-8甚至是ASCII兼容的编码)。如果您确实希望将密钥表示为文字字符串,请至少使用显式编码,例如:CHUNK_ENCRYPTION_KEY.getBytes("UTF-8")
答案 1 :(得分:1)
在README中没有明确说明“JCE Unlimited Strength Jurisdiction Policy Files”应该被复制到JDK中的jre,否则它将无效。文件路径应为:/path/to/jdk1.7.0_xx/jre/lib/security
答案 2 :(得分:-1)
也许你提供的KEY和Initialization Vector没有32个字节,长度分别为16个字节。您还可以尝试使用不接受键的偏移量和长度参数的构造函数:
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);