0
votes

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 i-e 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.

3

3 Answers

0
votes

Is it possible that you have the wrong private key? How can you verify that it matches the public key?

0
votes

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

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)