Re: com.nimbusds.jose.JOSEException: Padding error in decryption

NareshFiserv
New Contributor

com.nimbusds.jose.JOSEException: Padding error in decryption

Team, 

Below is the code, getting padding exception while decrypting . 

------- code -----------------


public class Test2 {
private static final String BEGIN_RSA_PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----";
private static final String END_RSA_PRIVATE_KEY = "-----END RSA PRIVATE KEY-----";
private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
private static final String END_CERT = "-----END CERTIFICATE-----";

public static void main(String[] args) throws Exception{
try {

String encryptedString = getEncryptedPayload("This is a sample text");
getDecryptedPayload(encryptedString, String.class);

} catch (IOException e) {
e.printStackTrace();
}
}

private static String getEncryptedPayload(Object payload) throws CertificateException, JOSEException, IOException {

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
String plainText = payload == null ? "" : payload.toString();
JWEHeader.Builder headerBuilder = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM);
String keyId = "b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42";
headerBuilder.keyID(keyId);
headerBuilder.customParam("iat", System.currentTimeMillis());
JWEObject jweObject = new JWEObject(headerBuilder.build(), new Payload(plainText));
jweObject.encrypt(new RSAEncrypter(getRSAPublicKey()));
//return "{\"encData\":\""+jweObject.serialize()+"\"}";
return jweObject.serialize();
}

private static RSAPublicKey getRSAPublicKey() throws CertificateException, IOException {
String mleServerPublicCertificatePath = "C:/code/server_cert_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem";
String pemEncodedPublicKey = IOUtils.readFileToString(new File(mleServerPublicCertificatePath), Charset.forName("UTF-8"));
com.nimbusds.jose.util.Base64 base64 = new com.nimbusds.jose.util.Base64( pemEncodedPublicKey.replaceAll(BEGIN_CERT, "").replaceAll(END_CERT, ""));
Certificate cf = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(base64.decode()));
return (RSAPublicKey) cf.getPublicKey();
}

public static <T> T getDecryptedPayload(Object encryptedPayload, Class<T> returnType) {

String response = encryptedPayload.toString();
T decryptedResponse = null;
try {
JWEObject jweObject = JWEObject.parse(response);
jweObject.decrypt(new RSADecrypter(getRSAPrivateKey("C:/code/key_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem")));

// in above line, RSAPrivateKey is formed successfully, but there is padding exception 
response = jweObject.getPayload().toString();
ObjectMapper mapper = new ObjectMapper();
decryptedResponse = mapper.readValue(response, returnType);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedResponse;
}

private static PrivateKey getRSAPrivateKey(String filePath) throws Exception {
String pemEncodedKey = IOUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
com.nimbusds.jose.util.Base64 base64 = new com.nimbusds.jose.util.Base64(pemEncodedKey.replaceAll(BEGIN_RSA_PRIVATE_KEY, "").replaceAll(END_RSA_PRIVATE_KEY, ""));
ASN1Sequence primitive = (ASN1Sequence) ASN1Sequence.fromByteArray(base64.decode());
Enumeration<?> e = primitive.getObjects();
BigInteger v = ((ASN1Integer) e.nextElement()).getValue();
int version = v.intValue();
if (version != 0 && version != 1) {
throw new IllegalArgumentException("wrong version for RSA private key");
}
BigInteger modulus = ((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
BigInteger privateExponent = ((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, privateExponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");

return (PrivateKey) keyFactory.generatePrivate(privateKeySpec);
}
}

----------------- Exception details ----------

com.nimbusds.jose.JOSEException: Padding error in decryption
at com.nimbusds.jose.crypto.RSA_OAEP_256.decryptCEK(RSA_OAEP_256.java:119)
at com.nimbusds.jose.crypto.RSADecrypter.decrypt(RSADecrypter.java:242)
at com.nimbusds.jose.JWEObject.decrypt(JWEObject.java:415)
at org.example.Test2.getDecryptedPayload(Test2.java:93)
at org.example.Test2.main(Test2.java:50)
Caused by: javax.crypto.BadPaddingException: Padding error in decryption
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:389)

-----------------

4 REPLIES 4
SyedSa
Community Moderator

Re: com.nimbusds.jose.JOSEException: Padding error in decryption

Hi @NareshFiserv, Thank you for reaching out. An agent will get back to you as soon as possible. Until then, if any community member has information that may be helpful, feel free to reply in this thread.

NareshFiserv
New Contributor

Re: com.nimbusds.jose.JOSEException: Padding error in decryption

I am using a sample string to encrypt which returns encryptedString, and using the same encryptedString to decrypt. Is this way of testing correct ? Or, is there any specific way to test this encryption / decryption mechanism end to end ? 

NareshFiserv
New Contributor

Re: com.nimbusds.jose.JOSEException: Padding error in decryption

 

1. 

I have downloaded the privateKey(key_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem) file and publicKey (server_cert_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem) file from Vis Developer Platform portal. 

2. 

I am using a sample string to encrypt which returns encryptedString, and using the same encryptedString to decrypt.

Is this way of testing correct ?

Or, is there any specific way to test this encryption / decryption mechanism end to end ? 

DianaVisaPM
Visa Developer Support Specialist

Re: com.nimbusds.jose.JOSEException: Padding error in decryption

Hey @NareshFiserv,

 

Certainly, here's the revised code without the bold emphasis:

```java
// START 
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.RSADecrypter;
import com.nimbusds.jose.crypto.RSAEncrypter;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Sequence;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.util.Enumeration;

public class Test2 {
private static final String BEGIN_RSA_PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----";
private static final String END_RSA_PRIVATE_KEY = "-----END RSA PRIVATE KEY-----";
private static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
private static final String END_CERT = "-----END CERTIFICATE-----";

public static void main(String[] args) {
try {
String encryptedString = getEncryptedPayload("This is a sample text");
getDecryptedPayload(encryptedString, String.class);
} catch (Exception e) {
e.printStackTrace();
}
}

private static String getEncryptedPayload(Object payload) throws CertificateException, JOSEException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
String plainText = payload == null ? "" : payload.toString();
JWEHeader.Builder headerBuilder = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM);
String keyId = "b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42";
headerBuilder.keyID(keyId);
headerBuilder.customParam("iat", System.currentTimeMillis());
JWEObject jweObject = new JWEObject(headerBuilder.build(), new Payload(plainText));
jweObject.encrypt(new RSAEncrypter(getRSAPublicKey()));
return jweObject.serialize();
}

private static RSAPublicKey getRSAPublicKey() throws CertificateException, IOException {
String mleServerPublicCertificatePath = "C:/code/server_cert_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem";
String pemEncodedPublicKey = IOUtils.readFileToString(new File(mleServerPublicCertificatePath), Charset.forName("UTF-8"));
pemEncodedPublicKey = pemEncodedPublicKey.replaceAll(BEGIN_CERT, "").replaceAll(END_CERT, "").replaceAll("\\s", "");
com.nimbusds.jose.util.Base64 base64 = new com.nimbusds.jose.util.Base64(pemEncodedPublicKey);
Certificate cf = CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(base64.decode()));
return (RSAPublicKey) cf.getPublicKey();
}

private static <T> T getDecryptedPayload(Object encryptedPayload, Class<T> returnType) {
String response = encryptedPayload.toString();
T decryptedResponse = null;
try {
JWEObject jweObject = JWEObject.parse(response);
jweObject.decrypt(new RSADecrypter(getRSAPrivateKey("C:/code/key_b1eaf5f7-2f6f-4429-96cb-8a2ee312ae42.pem")));
response = jweObject.getPayload().toString();
ObjectMapper mapper = new ObjectMapper();
decryptedResponse = mapper.readValue(response, returnType);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedResponse;
}

private static PrivateKey getRSAPrivateKey(String filePath) throws Exception {
String pemEncodedKey = IOUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
pemEncodedKey = pemEncodedKey.replaceAll(BEGIN_RSA_PRIVATE_KEY, "").replaceAll(END_RSA_PRIVATE_KEY, "").replaceAll("\\s", "");
com.nimbusds.jose.util.Base64 base64 = new com.nimbusds.jose.util.Base64(pemEncodedKey);
ASN1Sequence primitive = (ASN1Sequence) ASN1Sequence.fromByteArray(base64.decode());
Enumeration<?> e = primitive.getObjects();
BigInteger v = ((ASN1Integer) e.nextElement()).getValue();
int version = v.intValue();
if (version != 0 && version != 1) {
throw new IllegalArgumentException("wrong version for RSA private key");
}
BigInteger modulus = ((ASN1Integer) e.nextElement()).getValue();
((ASN1Integer) e.nextElement()).getValue();
BigInteger privateExponent = ((ASN1Integer) e.nextElement()).getValue();
RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(modulus, privateExponent);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(privateKeySpec);
}
}
// END
```

 

Key Points:
1. Remove White Spaces:
Ensure that all whitespaces, including newline characters, are removed when parsing the PEM-encoded keys. This is done using `.replaceAll("\\s", "")`.

2. Encoding and Decoding:
Double-check the encoding and decoding process for any errors.

3. Exception Handling:
Added more comprehensive exception handling to catch and display errors during the encryption/decryption process.

 

Testing:
- Encrypt a sample string using the `getEncryptedPayload` method.
- Immediately decrypt the encrypted string using the `getDecryptedPayload` method.

 




Thanks,

Diana



Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.