解密时使用PKCS7Padding时出现问题。使用IvParameterSpec或AlgorithmParameters来提供它

时间:2017-05-03 13:36:24

标签: android encryption keystore android-keystore

如何解密下面示例中已加密的字符串,当我使用下面的代码时,我得到异常

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()每次运行应用程序时都会返回随机密钥。

2 个答案:

答案 0 :(得分:2)

Cipher的init方法的java doc说

  

如果此密码需要任何算法参数且params为null,则底层密码实现应该自行生成所需的参数(使用特定于提供程序的默认值或随机值),如果它正在初始化以进行加密或密钥换行,并且InvalidAlgorithmParameterException,如果它正在初始化以进行解密或密钥解包。可以使用getParameters或getIV(如果参数是IV)检索生成的参数。

因此,如果您未通过Algorithm parametersinit方法中的第3个参数),则每次都会生成随机参数。因此,当您执行encryptionCipher.getIV()时,每次都会返回不同的内容。

如果您需要使用IV(建议使用):

  • 您可以使用固定值来初始化您的密码(不是高度安全的)
  • 或者您可以每次生成随机IV(更安全)并将其与加密值一起存储,并在解密时解析。

答案 1 :(得分:1)

您需要记录加密时使用的 IV ,并将其与加密数据一起提供,以便在解密时可用。

执行此操作的一种简单方法是使用 IV 预先加密加密数据,然后在解密之前获取/删除它。 IV不需要保密,但每次加密都应该不同。