use*_*000 5 java encryption aes secret-key initialization-vector
为什么这个init会成功:
Cipher AESCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AESCipher.init(Cipher.ENCRYPT_MODE, secretKey, secRandom);
Run Code Online (Sandbox Code Playgroud)
虽然失败了:
Cipher AESCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AESCipher.init(Cipher.DECRYPT_MODE, secretKey, secRandom);
Run Code Online (Sandbox Code Playgroud)
在线程"main"中抛出异常java.security.InvalidKeyException:缺少参数
secretKey由KeyGenerator生成,secureRandom由SecureRandom.getInstance("SHA1PRNG")生成,具有随机静态种子集.
谢谢
正如CodeInChaos正确推测的那样,SecureRandom实例用于在AESCipher创建实例时派生随机IV Cipher.ENCRYPT_MODE.但是,在解密模式下创建Cipher实例时,请将其作为参数提供.这个小小的无意义代码片段显示了一个例子.
public static void main(String[] args) throws Exception {
SecureRandom secRandom = SecureRandom.getInstance("SHA1PRNG");
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, secRandom);
Key secretKey = kg.generateKey();
Cipher AESCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AESCipher.init(Cipher.ENCRYPT_MODE, secretKey, secRandom);
IvParameterSpec iv = new IvParameterSpec(AESCipher.getIV());
AESCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
AESCipher.init(Cipher.DECRYPT_MODE, secretKey,iv, secRandom);
}
Run Code Online (Sandbox Code Playgroud)
此外,您声称使用静态种子初始化SecureRandom实例表明您对该类的误解.当您提供相同的种子时,SecureRandom不保证您将获得相同的输出.如果你仔细看看Javadocs,你会发现它试图从其他来源提供一些真正的熵,如果可能的话.
编辑1:
感谢owlstead在审查答案时通常的彻底性.有关其他讨论,请参阅他对相关问题的回答.SHA1PRNG的源代码可在此处在线获取.遵循这一点有点棘手,但如果在向实例询问任何随机字节之前提供种子,那么输出将是完全确定的.所以我之前的陈述不正确.