gpt4 book ai didi

java - AES/ECB/PKCS5Padding 如何正确填充最后一个 block ?

转载 作者:行者123 更新时间:2023-11-29 07:31:26 25 4
gpt4 key购买 nike

我遇到了这个异常:

javax.crypto.BadPaddingException: Given final block not properly padded

奇怪的是,这只发生在某些字符串上,以一种不可预测的方式,所以我不知道如何修复它。

这是完整的异常:

javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)

这是我的代码:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class Crypt {

private Crypt() {
}

public static String encrypt(String key, String toEncrypt) {
byte[] toEncryptBytes = toEncrypt.getBytes();
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, getKey(key));
byte[] encrypted = cipher.doFinal(toEncryptBytes);
return new String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}

public static String decrypt(String key, String toDecrypt) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, getKey(key));
byte[] decrypted = cipher.doFinal(toDecrypt.getBytes());
return new String(decrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}

private static SecretKeySpec getKey(String str) {
byte[] bytes = str.getBytes();
try {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
bytes = sha.digest(bytes);
bytes = Arrays.copyOf(bytes, 16);
return new SecretKeySpec(bytes, "AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

public static final void main(String[] args) {
String key = "KEY123";
String toEncrypt = "0";
boolean[] b = new boolean[128];
for (int i = 0; i < 128; i++) {
if (test(key, toEncrypt) == false) {
System.err.println("ERROR with size " + toEncrypt.length());
} else {
b[i] = true;
}
toEncrypt += "0";
}

System.out.println("Following sizes don't work:");
for (int i = 0; i < b.length; i++) {
if (!b[i]) {
System.out.println(i + 1);
}
}
}

// true = success
public static boolean test(String key, String toEncrypt) {
try {
System.out.print(toEncrypt.length() + ": ");
String encrypted = encrypt(key, toEncrypt);
System.out.print(encrypted + "; ");

String decrypted = decrypt(key, encrypted);
System.out.println(decrypted);

if (decrypted == null) {
return false;
}

if (toEncrypt.equals(decrypted)) {
return true;
}
return false;
} catch (Throwable t) {
return false;
}
}
}

运行此代码后,我得到以下输出:

Following sizes don't work:
3
6
10
11
15
18
22
23
27
30
34
35
39
42
46
47
51
54
58
59
63
66
70
71
75
78
82
83
87
90
94
95
99
102
106
107
111
114
118
119
123
126

但是,当我更改要加密的字符串时,这些数字会发生变化,例如当我使用“1”而不是“0”时。

我如何让它工作?如何正确填充最后一个 block ?

提前致谢。

最佳答案

您没有向解密函数提供加密函数的确切输出。

加密产生一个字节数组。然而,您将其转换为字符串,它将以某种方式解释字节数组(取决于平台字符集)。

要么保留字节数组本身,要么将字节数组转换为十六进制字符串或 Base64 字符串。例如:

        byte[] encrypted = cipher.doFinal(toEncryptBytes);
return Base64.getEncoder().encode(encrypted); // Uses Java 8 java.util.Base64

关于java - AES/ECB/PKCS5Padding 如何正确填充最后一个 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41660349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com