使用相同的密钥解密AES时BadPaddingException

这是测试人员:

public class CryptographySimpleTests extends ActivityTestCase { public void testsCryptographyClass_encryptAndDecrypt() { final String orgVal = "hi world! :D"; final String key = "key"; try { final byte[] encryptKey = Cryptography.deriveAES256Key(key); final byte[] decryptKey = Cryptography.deriveAES256Key(key); //Deviation method Assert.assertTrue(Arrays.equals(encryptKey, decryptKey)); byte[] encrypted = Cryptography.encryptAES(encryptKey, orgVal.getBytes()); Assert.assertFalse(Arrays.equals(encrypted, orgVal.getBytes())); byte[] decrypted = Cryptography.decryptAES(decryptKey, encrypted); Assert.assertTrue(Arrays.equals(orgVal.getBytes(), decrypted)); } catch (Exception e) { Assert.fail(e.getMessage()); } } } 

因为最后一个断言而失败了:

 Assert.fail(e.getMessage()); 

尝试执行时:

 byte[] decrypted = Cryptography.decryptAES(decryptKey, encrypted); 

给出这个堆栈跟踪:

 javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method) at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430) at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466) at javax.crypto.Cipher.doFinal(Cipher.java:1340) at bdevel.encuentralo.utils.Cryptography.decryptAES(Cryptography.java:59) at bdevel.encuentralo.CryptographySimpleTests.testsCryptographyClass_encryptAndDecrypt(CryptographySimpleTests.java:32) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214) at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199) at junit.framework.TestCase.runBare(TestCase.java:134) at junit.framework.TestResult$1.protect(TestResult.java:115) at junit.framework.TestResult.runProtected(TestResult.java:133) at junit.framework.TestResult.run(TestResult.java:118) at junit.framework.TestCase.run(TestCase.java:124) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837) 

这些是我的function:

 public class Cryptography { /** * @param key AES Key * @param inputValue Data to encrypt * @return Can return null if something goes wrong */ public static byte[] encryptAES(byte[] key, byte[] inputValue) throws NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { SecretKeySpec sKeyS = new SecretKeySpec(key, "AES"); Cipher cipher = null; try { cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, sKeyS); } catch (NoSuchAlgorithmException | InvalidKeyException i) { cipher = null; } return cipher != null ? cipher.doFinal(inputValue) : null; } public static byte[] decryptAES(byte[] key, byte[] encryptedData) throws NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { SecretKeySpec sKeyS = new SecretKeySpec(key, "AES"); Cipher cipher = null; try { cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, sKeyS); } catch (NoSuchAlgorithmException | InvalidKeyException i) { cipher = null; } return cipher != null ? cipher.doFinal(encryptedData) : null; } private static byte[] deriveAES256KeySalt = null; public static byte[] deriveAES256Key(String password) throws InvalidKeySpecException, NoSuchAlgorithmException { /* Store these things on disk used to derive key later: */ int iterationCount = 1000; int saltLength = 32; // bytes; should be the same size as the output (256 / 8 = 32) int keyLength = 256; // 256-bits for AES-256, 128-bits for AES-128, etc /* When first creating the key, obtain a salt with this: */ if(deriveAES256KeySalt == null) { SecureRandom random = new SecureRandom(); deriveAES256KeySalt = new byte[saltLength]; random.nextBytes(deriveAES256KeySalt); } /* Use this to derive the key from the password: */ KeySpec keySpec = new PBEKeySpec(password.toCharArray(), deriveAES256KeySalt, iterationCount, keyLength); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); return keyBytes; } } 

如果检查密钥是否相同的断言有效,为什么我会得到该exception?

您正在吃java.security.InvalidKeyException: Illegal key size or default parameters您的encryptAESdecryptAES方法中存在java.security.InvalidKeyException: Illegal key size or default parametersexception。 所以不要吃它们,要么声明为throws ,要么提升为RuntimeException

原来你有两个问题, 因为这个原因 ,你不能做256,但是128解决了这个问题,那么你也在没有IvParameterSpec请求CBC (导致java.security.InvalidKeyException: Parameters missing )。 那么为ECB提供或改变:

 public static byte[] encryptAES(byte[] key, byte[] inputValue) throws NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException { SecretKeySpec sKeyS = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, sKeyS); return cipher.doFinal(inputValue); } public static byte[] decryptAES(byte[] key, byte[] encryptedData) throws NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException { SecretKeySpec sKeyS = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, sKeyS); return cipher.doFinal(encryptedData); } 

密钥长度:

 public static byte[] deriveAES256Key(String password) throws InvalidKeySpecException, NoSuchAlgorithmException { ... int keyLength = 128; // 256-bits for AES-256, 128-bits for AES ... 

所以我得到了这样的工作,但第一步是停止吃exception,你会得到更好的线索,并可能自己解决。

我在没有IvParameterSpec的情况下使用CBC。

解决了添加以下内容以加密和解密:

 cipher.init(Cipher."mode here", sKeyS, getIvSpecAES256()); 

其中“getIvSpecAES256()”始终返回相同的值。