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

Request processing failed; nested exception is javax.crypto.BadPaddingException: Decryption error

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

这是问题的详细信息。 在一种控制器方法中,我使用 AES 对称密钥进行文件加密,然后使用其他用户 public 密钥加密 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 实例,用于加密和解密,但这也不起作用。

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

我不知道我哪里错了或者我错过了什么。非常感谢您的帮助。谢谢。

有没有可能你私钥有误?您如何验证它是否与 public 键匹配?

这样我的问题就解决了。 我已将密码设为静态并在静态块中对其进行初始化。 然后我在两种控制器方法中使用相同的密码。

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();
    }
}

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

要使用 RSA 加密对称密钥,请使用 Cipher.WRAP_MODECipher.wrap(key)。默认 RSA/ECB/PKCS1Padding 只能包装密钥,不能加密 "normal" 数据。 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 应该能够正常加密但不能包装密钥。 (虽然我不知道为什么)