AES / CBC / PKCS5Padding问题

我正在尝试加密和解密一些简单的文本。 但由于某种原因,我收到一个奇怪的错误: javax.crypto.BadPaddingException 。 为什么JCE会生成未正确填充的字节?

我有以下代码:

 import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import java.security.SecureRandom; public class SimplestTest { public static void main(String[] args) throws Exception { SecureRandom rnd = new SecureRandom(); String text = "Hello, my dear! ... " + System.getProperty("user.home"); byte[] textData = text.getBytes(); IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16)); KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(128); SecretKey k = generator.generateKey(); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); c.update(textData); byte[] data = c.doFinal(); System.out.println("E: " + data.length); c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, k, iv); c.update(data); System.out.println("R: " + c.doFinal().length); } } 

但由于某种原因,它不起作用。 它失败了,有这个例外:

 E: 16 Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..) at javax.crypto.Cipher.doFinal(DashoA13*..) at SimplestTest.main(SimplestTest.java:31) 

出了什么问题? 数据大小长度为16个字节,但仍然“未正确填充”?

Cipher.update也返回一个byte []。 因此,当您进行解密时,您将丢失部分加密数据。 更新最后一节如下:

 Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] someData = c.update(textData); byte[] moreData = c.doFinal(); System.out.println("E: " + (someData.length + moreData.length)); c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, k, iv); byte[] someDecrypted = c.update(someData); byte[] moreDecrypted = c.doFinal(moreData); System.out.println("R: " + (someDecrypted.length + moreDecrypted.length)); 

您可以放弃update调用,只需将byte[]数据直接传递给doFinal ,即可一步执行加密或解密操作。