请原谅hackjob!编码时仍然很新,并且正在利用大量的系统输出进行故障排除,这是我在StackOverflow上的第一篇文章。谢谢你的帮助!
所以我一直在努力尝试使用javax.crypto.Cipher API加密String对象,并且我已经找到了一些成功,但只有当它使用相同的Cipher对象实例时。但是,出于我的项目的目的,我正在加密文本(String)和解密文本文件中的文本,并且每次都不会访问相同的Cipher对象。
我认为问题不在于字节数组和字符串之间的转换,因为Base64编码器似乎已经解决了这个问题。字节数组的输出在预编码和后解码时是相同的,因此在解密阶段应将其隔离为一个问题。可以做什么,以便我的decryptPW方法可以使用不同的Cipher实例(传递相同的参数)而不会触发BadPaddingException?
private static String encryptPW(String pw){
byte[] pwBytes = pw.getBytes();
byte[] keyBytes = "0123456789abcdef".getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
try {
Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding");
ciph.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] encryptedBytes = ciph.doFinal(pwBytes);
pw = Base64.getEncoder().encodeToString(ciph.doFinal(pwBytes));
for (byte b : encryptedBytes){
System.out.print(b);
}
System.out.println();
} catch (Exception e){
e.printStackTrace();
}
return pw;
}
private static String decryptPW(String pw){
byte[] pwBytes = Base64.getDecoder().decode(pw.getBytes());
for (byte b : pwBytes){
System.out.print(b);
}
System.out.println();
byte[] keyBytes = "0123456789abcdef".getBytes();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
try {
Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding");
ciph.init(Cipher.DECRYPT_MODE, keySpec, ciph.getParameters());
pw = new String(ciph.doFinal(pwBytes));
} catch (Exception e){
e.printStackTrace();
}
return pw;
}
再次,谢谢!
答案 0 :(得分:1)
在使用CBC mode时,您需要从加密密码中保存随机初始化向量(IV)并将其提供给解密密码。
你可以在init之后从加密密码中获取它:
ciph.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] iv = ciph.getIV();
并将其提供给解密密码,例如:
ciph.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
你需要想出一种保存IV的方法。常见的方法是使用IV为加密数据添加前缀,以便在需要初始化解密密码时可以使用它。它不需要保密。