简体   繁体   中英

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. But I am getting the error 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.

    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.

       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.

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. I have also made static Cipher instances in my application,to encrypt and decrypt but that doesn't work either.

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. Take a look at How to avoid installing "Unlimited Strength" JCE policy files when deploying an application? then you should also make sure to use 2048 or more on RSA ;)

For encrypting a symmetic key with RSA use Cipher.WRAP_MODE and Cipher.wrap(key) . The default RSA/ECB/PKCS1Padding can only wrap keys and not encrypt "normal" data. RSA/ECB/OAEPWithSHA-256AndMGF1Padding should be able to encrypt normaly but cannot wrap keys. (I have no Idea why though)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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