简体   繁体   English

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

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

I am trying to share a symmetric key encrypted with Asymmetric encryption, between two users in a spring web application. 我试图在Spring Web应用程序中的两个用户之间共享使用非对称加密加密的对称密钥。 But I am getting the error javax.crypto.BadPaddingException. 但是我收到错误javax.crypto.BadPaddingException。

Here is detail of problem. 这是问题的细节。 In one controller method I am using AES symmetric key for file encryption, then encrypting the AES secret key with the other user public key and saving it into MySQL database. 在一种控制器方法中,我使用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

In controller's other method I am getting the encrypted secretkey from database ,decrypting the secretkey using private key. 在控制器的另一种方法中,我从数据库中获取加密的密钥,并使用私钥解密该密钥。 Building a new Secret AES Key to decrypt the encrypted file. 构建新的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());

But it is giving error when I am decrypting the encrypted symmetric key using PrivateKey at this line of code. 但是,当我在此行代码中使用PrivateKey解密加密的对称密钥时,它给出了错误。

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

It is giving this error 它给这个错误

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)

Help me out in this please. 请帮助我。 I have used a same approach in a simple java application [one main function] where it is working perfectly. 我在一个简单的Java应用程序[一个主要功能]中使用了相同的方法,在该应用程序中它可以完美地工作。 I have also made static Cipher instances in my application,to encrypt and decrypt but that doesn't work either. 我还在应用程序中制作了静态Cipher实例,以进行加密和解密,但这也不起作用。

One more thing When I have decrypt the encrypted symmetric key in the same controller method ie encryption and decryption takes place in one method, it works fine. 还有一件事情,当我以相同的控制器方法解密了加密的对称密钥时,即以一种方法进行加密和解密时,它可以正常工作。

I don't know where I am going wrong or what I am missing. 我不知道我哪里出了问题或我错过了什么。 The help will be really appreciated. 的帮助将不胜感激。 Thanks. 谢谢。

Is it possible that you have the wrong private key? 您是否可能使用了错误的私钥? How can you verify that it matches the public key? 您如何验证它与公钥匹配?

My problem is solved by doing this. 通过这样做可以解决我的问题。 I have made the Ciphers static and initialized them in static blocks. 我已将密码器设为静态,并在静态块中对其进行了初始化。 Then I am using the same ciphers in both controller methods. 然后我在两种控制器方法中使用相同的密码。

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

AES with keysize 128 is not very effective. 密钥大小为128的AES不太有效。 Take a look at How to avoid installing "Unlimited Strength" JCE policy files when deploying an application? 看一下如何在部署应用程序时避免安装“无限强度” JCE策略文件? then you should also make sure to use 2048 or more on RSA ;) 那么您还应该确保在RSA上使用2048或更大值;)

For encrypting a symmetic key with RSA use Cipher.WRAP_MODE and Cipher.wrap(key) . 要使用RSA加密对称密钥,请使用Cipher.WRAP_MODECipher.wrap(key) The default RSA/ECB/PKCS1Padding can only wrap keys and not encrypt "normal" data. 默认的RSA/ECB/PKCS1Padding仅可以包装密钥,而不能加密“常规”数据。 RSA/ECB/OAEPWithSHA-256AndMGF1Padding should be able to encrypt normaly but cannot wrap keys. RSA/ECB/OAEPWithSHA-256AndMGF1Padding应该能够正常加密,但是不能包装密钥。 (I have no Idea why though) (我不知道为什么)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM