Java AES加解密报错:javax.crypto.IllegalBlockSizeException求助
AES/CBC/PKCS5Padding加解密报错IllegalBlockSizeException问题排查
我是Java AES开发新手,学习256位AES加解密时遇到如下错误:
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Message must be a multiple of the block size without padding
测试输入"hello"或"dFet4Q2fi"都会触发该错误,目前对错误根源及代码修改方向感到困惑,仅了解AES/CBC/PKCS5Padding代表算法/模式/填充方式。
我的代码实现
main方法
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException, InvalidKeySpecException { System.out.println("Encrypt/Decrypt a string"); //3 params for AES algo: (1) input data, (2) secret key, (3) and IV Scanner scanner = new Scanner(System.in); String inputKey; int inputSecretKey = 256; IvParameterSpec IV; //step 1: input System.out.print("Input: "); inputKey = scanner.nextLine(); //step 2: generate secret key System.out.println("Generating secret key with size "+inputSecretKey); SecretKey secretKey1 = generateKey(inputSecretKey); //step 3: generate IV IV = generateIv(); //step 4: print String cipherText = encrypt("AES/CBC/PKCS5Padding", inputKey, secretKey1, IV); String plainText = decrypt("AES/CBC/PKCS5Padding", inputKey, secretKey1, IV); Assertions.assertEquals(inputKey, plainText); System.out.println("Encrypted: "+cipherText+" [size : "+cipherText.length()+"]"); System.out.println("Decrypted: "+plainText+" [size : "+plainText.length()+"]"); scanner.close(); }
generateKey方法
public static SecretKey generateKey(int n) throws NoSuchAlgorithmException { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(n); SecretKey key = keyGen.generateKey(); return key; }
generateIv方法
public static IvParameterSpec generateIv() { byte[] iv = new byte[16]; new SecureRandom().nextBytes(iv); return new IvParameterSpec(iv); }
encrypt方法
public static String encrypt(String algorithm, String input, SecretKey key, IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] cipherText = cipher.doFinal(input.getBytes()); return Base64.getEncoder() .encodeToString(cipherText); }
decrypt方法(报错行标注)
public static String decrypt(String algorithm, String cipherText, SecretKey key, IvParameterSpec iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, key, iv); byte[] plainText = cipher.doFinal(Base64.getDecoder() .decode(cipherText)); //<-------- 此处报错 return new String(plainText); }
错误根源与修复方案
你犯了一个基础的参数传递错误:在main方法调用decrypt时,传入的第二个参数是原始明文inputKey,而不是加密后得到的cipherText!
// 错误代码: String plainText = decrypt("AES/CBC/PKCS5Padding", inputKey, secretKey1, IV); // 正确代码: String plainText = decrypt("AES/CBC/PKCS5Padding", cipherText, secretKey1, IV);
decrypt方法要求第二个参数是Base64编码的密文,但你传入了明文字符串,Base64解码后的字节数组长度几乎不可能是AES块大小(16字节)的整数倍,因此触发了IllegalBlockSizeException。
修正该参数后,代码即可正常运行。另外补充两点注意事项:
- 加密和解密必须使用同一个IV(当前代码已满足该要求)
- JDK8及以下版本使用256位AES需安装JCE扩展,新版本JDK默认已支持256位密钥
内容的提问来源于stack exchange,提问作者essinaya
相关产品推荐
相关产品推荐

