我得到这个例外:
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"时.
我如何让它工作?如何正确填充最终块?
提前致谢.
您没有向decrypt函数提供加密函数的确切输出.
加密产生一个字节数组.但是,您可以将其转换为String,它将以某种方式解释字节数组(取决于平台字符集).
保留字节数组本身,或将字节数组转换为十六进制字符串或Base64字符串.例如:
byte[] encrypted = cipher.doFinal(toEncryptBytes); return Base64.getEncoder().encode(encrypted); // Uses Java 8 java.util.Base64