javax.crypto.BadPaddingException AES 256 CBC加密

时间:2011-10-22 00:03:58

标签: java cryptography

我正在尝试使用java中的PKCS5Padding为AES 256 CBC加密编写加密/解密方法。我目前正在尝试解密来自另一个Base64编码源的加密文本。

以下代码: (这只是测试数据所以它不敏感)

// JUnit Test
    @Test
    public void testDecrypt() {
        String cipherText = "rrAwZQCAIj19XauZE6tQEg/HQuWB7gw+1uVO0hylyWyCSJo/y7uB6Xj4BRVi+a3qY9GQ/ahjPdUF/kSHptt6QttkvQf89JS13Mo3mRAnaDK/8uoRur8TDuKzLtCSjaMAg72LqObx04+yLd9hI2krtCaWd2saCLP/cWvTQ9oc1xQ=";
        String iv = "o1clHzdEkUV4sFj72VwDFQ==";
        String syncKey = "gbh7teqqcgyzd65svjgibd7tqy";

        SecretKeySpec key = new SecretKeySpec(convertFromBase32(syncKey), "AES");
        byte[] cipherBytes = convertFromBase64(cipherText);
        System.out.println(cipherBytes.length);
        Encrypted d = Crypto.decrypt(new Encrypted(cipherBytes, key,
                convertFromBase64(iv)));
        String decryptedText = new String(d.getCipherText());
    }

// Actual Code
public static Encrypted decrypt(Encrypted encrypted) {
        // Initialize the Cipher
        Cipher cipher = null;
        IvParameterSpec ivParam = new IvParameterSpec(
                encrypted.getInitializationVector());
        try {
            cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, encrypted.getSymmetricKey(),
                    ivParam);
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (NoSuchPaddingException e1) {
            e1.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }

        byte[] outputBytes = cryptCommon(cipher, encrypted.getCipherText());
        Encrypted decrypted = new Encrypted(outputBytes,
                encrypted.getSymmetricKey(), cipher.getIV());
        return decrypted;
    }

    private static byte[] cryptCommon(Cipher cipher, byte[] inputBytes) {
        byte[] outputBytes = null;
        try {
            outputBytes = cipher.doFinal(inputBytes);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return outputBytes;
    }

我从Base64解码后检查字节[]的长度,它们的长度可以被块大小整除(对于16字节的块大小,它是128字节)。

这是我得到的堆栈跟踪:

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 com.mozilla.android.sync.Crypto.cryptCommon(Crypto.java:77)
    at com.mozilla.android.sync.Crypto.decrypt(Crypto.java:69)
    at com.mozilla.android.sync.test.CryptoTests.testDecrypt(CryptoTests.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

在密码学中,一切都必须准确。您是否将加密和解密方法都设置为PKCS5填充?您是否检查过加密方法产生的字节是否与解密函数消耗的字节完全匹配?

您是否检查过两个密钥完全匹配,字节为字节?您正在使用Base32,这有点不寻常。

我建议将您的测试细分为更小的部分,这样您就可以明确检查加密和解密的每个参数的匹配。确保将每个参数检查为字节数组,即不涉及到Base64或其他任何内容的转换。