1

I am trying to integrate an API where I have to send the data in RSA encrypted and BASE64 encoded form. In response I get a BASE64 String which is supposed to be decoded and decrypted at my end. I am able to send the data in encrypted and encoded form. Also I am getting the response BASE64 String but I am NOT ABLE TO DECRYPT the string. In my decryption I am getting following error:

Exception in thread "main" java.lang.RuntimeException: javax.crypto.BadPaddingException: Decryption error

I have used following for encryption:

        String result=new Gson().toJson(parameters);
        byte[] cleartext = result.getBytes("UTF-8");
        PublicKey publicKey=readPublicKey(path);

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");   
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        byte[] ciphertext=cipher.doFinal(cleartext);

        String securePayload = Base64.getEncoder().encodeToString(ciphertext);

Parameters is a (String,String) map and I have put the parameters in it that are required to POST in the API. After encryption I am sending "securePayload" in POST request and in response I am getting a BASE64 encoded string which I am supposed to decode and decrypt. For decryption I am using following code:

public static String getDecrypted(String data, PrivateKey key)  {
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

    cipher.init(Cipher.DECRYPT_MODE, key);

    byte[] dataArray=Base64.getDecoder().decode(data);
    byte[] decryptedbytes = cipher.doFinal(dataArray);
    return new String(decryptedbytes);
}

Above function I am using in following code to decrypt the String "data" which I am getting in API response:

    PrivateKey pvtKey= readFromPrivateKey("C:\\Users\\Administrator\\Desktop\\myPrivateKey.key");
    String result=getDecrypted(data, pvtKey);

To read the private key I have used following code:

    public static PrivateKey  readFromPrivateKey(String path) {

    String privateKeyContent = new String(Files.readAllBytes(Paths.get(path)));

    privateKeyContent = privateKeyContent.replaceAll(System.lineSeparator(), "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");
    System.out.println(privateKeyContent);
    KeyFactory kf = KeyFactory.getInstance("RSA");

    PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
    PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
    return privKey;
}

Please help in the same. What wrong am I doing? I have checked that the Public and Private key pair used at my end is correct.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
manish
  • 53
  • 7
  • 3
    What you've posted in your question *looks* ok. `new String(decryptedbytes);` should have the utf-8 charset argument, but the code never reaches that far so that isn't the problem. You *should* use hybrid encryption, both for security and to encrypt larger data such as what you're trying to encrypt. However, java doesn't enforce this and if your data size was too large you'd receive an error to that effect on encryption. I can only conclude that the problem lies outside of what's posted here, or what's posted here is not accurate. Perhaps the keys are not a matched pair. – President James K. Polk Oct 04 '19 at 10:40
  • Thanks a lot James for your response. I checked the pair is correct. Still not able to identify the error. – manish Oct 04 '19 at 11:23
  • The size of the data seems correct or you'd get another error, so I don't think the base 64 is transmitted OK. Since the algorithm is also OK, it *must* be the key pair that is not OK... – Maarten Bodewes Oct 05 '19 at 14:15

0 Answers0