请求处理失败;嵌套异常是javax.crypto.BadPaddingException:解密错误

时间:2015-05-18 20:07:04

标签: java security encryption cryptography encryption-asymmetric

我正在尝试在spring Web应用程序中的两个用户之间共享使用非对称加密加密的对称密钥。但是我收到了错误 javax.crypto.BadPaddingException。

这是问题的细节。 在一种控制器方法中,我使用AES对称密钥进行文件加密,然后使用其他用户公钥加密AES密钥并将其保存到MySQL数据库中。

    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128); 
    SecretKey secretKey = keyGen.generateKey();

    Cipher AESCipher= Cipher.getInstance("AES");
    AESCipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] cipherData = AESCipher.doFinal(file.getBytes());
    //storing cipherData in database

    Cipher RSACipher= Cipher.getInstance("RSA");
    RSACipher.init(Cipher.ENCRYPT_MODE, testPubKey);
    byte[] aesKeyEncryptedBytes = RSACipher.doFinal(secretKey.getEncoded());
    //storing aesKeyEncryptedBytes in Database

在控制器的其他方法中,我从数据库获取加密的密钥,使用私钥解密密钥。构建新的密钥AES密钥以解密加密文件。

       Cipher RSACipher= Cipher.getInstance("RSA");
       RSACipher.init(Cipher.DECRYPT_MODE, testPvtKey);
       //file.getSymmetricKey method give us the encrypted AES symmetric key from database
       byte[] decsymetricKeyBytes=RSACipher.doFinal(file.getSymetricKey());

        SecretKey symetricKey = new SecretKeySpec(decsymetricKeyBytes,
                "AES");

        Cipher AESCipher= Cipher.getInstance("AES");
        AESCipher.init(Cipher.DECRYPT_MODE, symetricKey);
        byte[] plainText = AESCipher.doFinal(file.getResourceFile());

但是当我在这行代码中使用PrivateKey解密加密的对称密钥时,它会出错。

byte[] decsymetricKeyBytes=RSACipher.doFinal(file.getSymetricKey());

提供此错误

May 19, 2015 12:30:27 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [/SP_SC_Hibernate] threw exception [Request processing failed; nested exception is javax.crypto.BadPaddingException: Decryption error] with root cause
javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
    at sun.security.rsa.RSAPadding.unpad(Unknown Source)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2121)
    at com.dynamic.spring.ResourceController.downloadAsymmetricFile(ResourceController.java:396)

请帮帮我。我在一个简单的java应用程序[一个主要功能]中使用了相同的方法,它完美地工作。 我还在我的应用程序中创建了静态Cipher实例,以进行加密和解密,但这也不起作用。

还有一件事当我在同一控制器方法中解密加密的对称密钥时,i-e加密和解密在一种方法中进行,它可以正常工作。

我不知道自己哪里出错了,或者我错过了什么。真的很感激帮助。感谢。

3 个答案:

答案 0 :(得分:0)

您是否可能有错误的私钥?如何验证它是否与公钥匹配?

答案 1 :(得分:0)

这样做可以解决我的问题。 我已经使Ciphers静态并在静态块中初始化它们。 然后我在两种控制器方法中使用相同的密码。

private static Cipher AESCipher = null;
private static Cipher RSACipher = null;

static {
    try {
        AESCipher = Cipher.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }
}

static {
    try {
        RSACipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    }
}

答案 2 :(得分:0)

使用keysize 128的AES效果不是很好。看看How to avoid installing "Unlimited Strength" JCE policy files when deploying an application?然后你还应该确保在RSA上使用2048或更多;)

使用Cipher.WRAP_MODECipher.wrap(key)加密带有RSA的symmetic密钥。默认RSA/ECB/PKCS1Padding只能包装密钥而不能加密“普通”数据。 RSA/ECB/OAEPWithSHA-256AndMGF1Padding应该能够正常加密但不能包装密钥。 (虽然我不知道为什么)