java javax.crypto.BadPaddingException: 鉴于最终块没有正确填充...尝试使用 getbytes("UTF")
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35853757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javax.crypto.BadPaddingException: Given final block not properly padded...tried using getbytes("UTF")
提问by sasha00
I have tried adding getbytes("UTF") or getbytes("UTF-8"), since it was suggested in a similar question. It said we need to try UTF while converting bytes to string and vice a versa. But still it is not working for my code...please help
我曾尝试添加 getbytes("UTF") 或 getbytes("UTF-8"),因为它是在类似问题中提出的。它说我们需要在将字节转换为字符串时尝试 UTF,反之亦然。但它仍然不适用于我的代码......请帮忙
public class Password1 {
private static final String ALGO = "AES";
private static byte[] keyValue = new byte[]{'t','h','y','u','e','f','z','s','y','k','f','l','d','a','b','m'};
public static void main(String[] args) {
//Password1 p = new Password1();
Scanner sc = new Scanner(System.in);
String i = sc.nextLine();
System.out.println("Password = "+i);
try {
String en = encrypt(i);
System.out.println(en);
String dec = decrypt(en);
System.out.println("Encrypted = " + en);
System.out.println("Decrypted = " + dec);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes("UTF-8"));
String encrypted = new BASE64Encoder().encode(encVal);
return encrypted;
}
public static String decrypt(String encrypted) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
//Byte bencrypted = Byte.valueOf(encrypted);
byte[] decoded = new BASE64Decoder().decodeBuffer(encrypted);
byte[] decValue = c.doFinal(decoded);
String decrypted = new String(decValue);
return decrypted;
}
private static Key generateKey() throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
keyValue = sha.digest(keyValue);
keyValue = Arrays.copyOf(keyValue, 16);
SecretKeySpec key = new SecretKeySpec(keyValue, ALGO);
return key;
}
}
回答by JB Nizet
When you call encrypt()
you replace the password by its hash, and then use the hash as a key.
当你打电话时,encrypt()
你用它的散列替换密码,然后使用散列作为密钥。
Then you call decrypt()
, and rehash the hash, and use the hashed hash as the key. So you're not using the same key for encryption and decryption.
然后你调用decrypt()
,并重新散列散列,并使用散列的散列作为键。因此,您没有使用相同的密钥进行加密和解密。
Generate the key oncein main()
, and pass it as parameter to encrypt()
and decrypt()
. Make keyValue
final. Or even better, make it a local variable of main
.
产生密钥一次的main()
,并且把它作为参数encrypt()
和decrypt()
。做keyValue
最后。或者甚至更好,使其成为main
.
回答by Aaron
On the line where you have Cipher.getInstance(ALGO)
have your ALGO
variable be "AES/CBC/PKCS5Padding"
(or whatever other mode and padding you want to use). This should resolve any padding issues you might run into like the one you are now.
在这里你有行Cipher.getInstance(ALGO)
有你的ALGO
变量"AES/CBC/PKCS5Padding"
(或任何其他模式和填充你想使用)。这应该可以解决您可能遇到的任何填充问题,就像您现在遇到的那样。
If you don't do it in this way I believe you'll have to handle all of the padding logic yourself.
如果你不这样做,我相信你必须自己处理所有的填充逻辑。
JB Nizet's answer about how you're generating keys is the other half of your problem.
JB Nizet 关于如何生成密钥的回答是问题的另一半。