如何解密下面示例中已加密的字符串,当我使用下面的代码时,我得到异常
String transforation = "AES/CBC/PKCS7Padding";
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);
// encrypt
Cipher cipher = Cipher.getInstance(transforation);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
String encriptedPassword = cipher.doFinal("Some Password".getBytes("UTF-8"));
// decrypt
cipher = Cipher.getInstance(transforation);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String password = new String(cipher.doFinal(encriptedPassword), "UTF-8"));
如果我提供 encryptCipher.getIV()我可以解密
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(encryptCipher.getIV()));
但问题是encryptCipher.getIV()每次运行应用程序时都会返回随机密钥。
答案 0 :(得分:2)
Cipher的init
方法的java doc说
如果此密码需要任何算法参数且params为null,则底层密码实现应该自行生成所需的参数(使用特定于提供程序的默认值或随机值),如果它正在初始化以进行加密或密钥换行,并且InvalidAlgorithmParameterException,如果它正在初始化以进行解密或密钥解包。可以使用getParameters或getIV(如果参数是IV)检索生成的参数。
因此,如果您未通过Algorithm parameters
(init
方法中的第3个参数),则每次都会生成随机参数。因此,当您执行encryptionCipher.getIV()
时,每次都会返回不同的内容。
如果您需要使用IV(建议使用):
答案 1 :(得分:1)
您需要记录加密时使用的 IV ,并将其与加密数据一起提供,以便在解密时可用。
执行此操作的一种简单方法是使用 IV 预先加密加密数据,然后在解密之前获取/删除它。 IV不需要保密,但每次加密都应该不同。