Exception:
javax.crypto.BadPaddingException: data hash wrong
org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown
Source)
javax.crypto.Cipher.doFinal(Cipher.java:2165)
com.mycompany.web.restfulws.EncryptionUtil.rsaDecryptWithRawPrivateKey(EncryptionUtil.java:207)
My Public Key is
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIs7W0XmYFjH415JDrOwuiSTnQOJXzKGOCDN2tbfqmDx+CD9VOs+0xSLKwg8towxmtmYTxF8vZy9Rk3jt3DarRQBlzjaT3dHsbaPZ72BNhfKnbk3WbIU8Eh7Ur1BrRCOxK8b4B7Q+iOCIf4CRF/JbYyebav1CfbbWLSZ1cl8ZUxQIDAQAB
My Private Key
MIICoTAbBgoqhkiG9w0BDAEDMA0ECDoNAO+O/RGtAgEUBIICgBZLXWRz+qpTxbOfxKBtSwvY3i/vcc39rvdgbmI+uFx5uUBrXlPgt0NB8bM7rtqm6OoFLcmyCSdwpmWS7qs9JxDZ5JQf0zsXT2UTsDN6tzeazuJPdrQWbk7VMUeWaI8E8cSFFtPF5R0Ab2bTo0wm/OOboKKtXlGAKL5CHC3KT87z8GpSfikVEfpMXfd/3zG5Q8FvsmcLjL9nnxCVb5CV2/9ghlZrvPknb6kKgUta/1y8ha6h7E9w23fIscjpHLD3TSP2JtigpfFPPv6MjeMaZMkHiuBQdJH7NVuOUM0OBRUsL+K5hsWReoqXqtPGRfAG4GUk6DP2yTwPSjv4dXWin+L5iYBxzgV8A0L+hJssrjUAo/gznMflKFw8xkcQ3UK0moMxSVzHeq/SRIowYfx9by1IJr8yRc1KqEHK+2lPApIMQBXn12Pnz/4ik+NkfOC7/Mk4QT718+SSzQmnJAq4sckh/k3lecxn3fW5T15LwjKiZFrxdXWclnuc0nMUlbQL8xL4Fwkz3bELTCwylECrugYvoHIhkaQx7/nLWO8To6zImWRTN9O6ietHiH3q5BnjDc4M59N8BeCZWIbYU+cJH8UDI596BZRfKo16WJXjguMDz3rJDOqEW/RjxYH90QdHTrxZlktVH5hKpTqKnNAXaUiB6I1+P6E2h7z3gGIgcXG6+rmpxzIpTxXF3I87MBz/wZpZQarBpGeMSXuOGvkVUvaxPiT9q7OxFWDv4Y79lYAlxKbsrgRlQDxJ8VhHmaX7E28EKk+c1h9lPREq2w2/bBQ/N5XrwLnf4K6yWAPLuyvQZYDJH4DunEyP+JKVZwUjxsu4MkvnwucdsM/1hX4Ttgc=
My message is pretty big (Specifically I need to decrypt Big JSON message in
my project). So I will use AES encryption for the message.
private static int iterations = 65536;
private static int keySize = 128;
private final static String TRANSFORMATION =
"RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
private final static String ENCODING = "UTF-8";
private final static String RSA_ALGORITHM = "RSA";
Step1: AES encypt the message.
public static String aesEncryptMessage(String toBeEncrypted) throws
Exception{
char[] plaintext = toBeEncrypted.toCharArray();
byte[] saltBytes = getSalt().getBytes();
SecretKeyFactory skf =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new
PBEKeySpec(plaintext,saltBytes,iterations,keySize);
SecretKey secretKey = skf.generateSecret(spec);
// Encode the secret
base64EncodedSecretKey =
BaseEncoding.base64().encode(secretKey.getEncoded());
SecretKeySpec secretSpec = new
SecretKeySpec(secretKey.getEncoded(),"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,secretSpec);
AlgorithmParameters params = cipher.getParameters();
byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
base64EncodedIVBytes = BaseEncoding.base64().encode(ivBytes);
byte[] encryptedTextBytes =
cipher.doFinal(String.valueOf(plaintext).getBytes("UTF-8"));
return DatatypeConverter.printBase64Binary(encryptedTextBytes);
}
Step2: RES encryption of the base64EncodedSecretKey
public static String rsaEncryptWithRawPublicKey(String rawText,String
publicKey) throws IOException,GeneralSecurityException{
byte[] publicKeyBase64Encoded = publicKey.getBytes(ENCODING);
byte[] base64DecodedPublicKeyBytes = BaseEncoding.base64().decode(new
String(publicKeyBase64Encoded).trim());
X509EncodedKeySpec x509EncodedKeySpec = new
X509EncodedKeySpec(base64DecodedPublicKeyBytes);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE,KeyFactory.getInstance(RSA_ALGORITHM).generatePublic(x509EncodedKeySpec));
return
org.apache.commons.codec.binary.Base64.encodeBase64String(cipher.doFinal(rawText.getBytes(ENCODING)));
}
Step3: The sender will exchange AES encrypted message + RES encrypted
password and the IVByets to the receiver
Step4: From the receiver end, Since the receiver has private key he will
decrypt the RES encrypted password
public static String rsaDecryptWithRawPrivateKey(String cipherText,String
privateKey) throws GeneralSecurityException, UnsupportedEncodingException{
byte[] privateKeyBase64Encoded = privateKey.getBytes(ENCODING);
byte[] base64DecodedPrivateKeyBytes = BaseEncoding.base64().decode(new
String(privateKeyBase64Encoded).trim());
PKCS8Key pkcs8 = new
PKCS8Key(base64DecodedPrivateKeyBytes,"pleaseChangeit!".toCharArray());
byte[] decrypted = pkcs8.getDecryptedBytes();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(decrypted);
// A Java PrivateKey object is born.
PrivateKey pk = null;
if (pkcs8.isDSA()) {
pk = KeyFactory.getInstance("DSA").generatePrivate(spec);
}
else if (pkcs8.isRSA()) {
pk = KeyFactory.getInstance("RSA").generatePrivate(spec);
}
// For lazier types:
pk = pkcs8.getPrivateKey();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new
PKCS8EncodedKeySpec(pk.getEncoded());
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE,KeyFactory.getInstance(RSA_ALGORITHM).generatePrivate(pkcs8EncodedKeySpec));
try {
return new
String(cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(cipherText)),ENCODING);
}
catch (BadPaddingException bpe) {
throw new ServiceFatalException("Bad Padding Exception. Here
was the text
to be decrypted ' "+cipherText+" '",bpe);
}
}
Step5: After getting the RES encoded password, receiver will decrypt the AES
encrypted message
public static String aesDecryptMessage(String encryptedMessage,String
base64EncodedEncryptedSecretKey,String base64EncodedEncryptedIVBytes){
byte[] decryptedTextBytes = null;
try {
byte[] encryptedTextBytes =
DatatypeConverter.parseBase64Binary(new
String(encryptedMessage));
byte[] base64DecodedEncryptedSecretKey =
Base64.getDecoder().decode(base64EncodedEncryptedSecretKey);
SecretKeySpec secretSpec = new
SecretKeySpec(base64DecodedEncryptedSecretKey,"AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] base64EncodedEncIVBytes =
Base64.getDecoder().decode(base64EncodedEncryptedIVBytes);
cipher.init(Cipher.DECRYPT_MODE,secretSpec,new
IvParameterSpec(base64EncodedEncIVBytes));
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
}
catch (Exception ex) {
}
return new String(decryptedTextBytes);
}
Overall
Sender will do :
String toBeEncrypted = "Hi!. How are you?";
String encrypted = aesEncryptMessage(toBeEncrypted);
System.out.println("XXX: "+encrypted);
String rsaEncryptedBase64EncodedSecretKey1 =
rsaEncryptWithRawPublicKey(getBase64EncodedSecretKey(),"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIs7W0XmYFjH415JDrOwuiSTnQOJXzKGOCDN2tbfqmDx+CD9VOs+0xSLKwg8towxmtmYTxF8vZy9Rk3jt3DarRQBlzjaT3dHsbaPZ72BNhfKnbk3WbIU8Eh7Ur1BrRCOxK8b4B7Q+iOCIf4CRF/JbYyebav1CfbbWLSZ1cl8ZUxQIDAQAB");
System.out.println(rsaEncryptedBase64EncodedSecretKey1);
System.out.println(getBase64EncodedIVBytes());
>From the receiver end
String encryptedMessage = "nlcJhSDU4c3CaeBrNVfsey6LDz1dT+GZT9hy25cmDOE=";
String base64EncodedSecretKey =
"DQJN55vKs1dj43NtvD/MgVqiuDdHEL+y2f56sxWhYcdskVvGZd1sq3PHL1HTAzjvWWLzA/QJGXFfdSH9K/LPGY/DqkOw2dxsTvNVV/EQoPCAGF6O7O5K4IVrez1DH0IxKIF3EcEldWcSIgpT2omJtAS4OKxdqY7MIG1Jd1Ph0P0=";
String base64EncodedIVBytes ="hzdwT6o8zgsqYnVAiP9Yhg==";
String
rsaDecryptedBase64EncodedSecretKey1=rsaDecryptWithRawPrivateKey(base64EncodedSecretKey,"MIICoTAbBgoqhkiG9w0BDAEDMA0ECDoNAO+O/RGtAgEUBIICgBZLXWRz+qpTxbOfxKBtSwvY3i/vcc39rvdgbmI+uFx5uUBrXlPgt0NB8bM7rtqm6OoFLcmyCSdwpmWS7qs9JxDZ5JQf0zsXT2UTsDN6tzeazuJPdrQWbk7VMUeWaI8E8cSFFtPF5R0Ab2bTo0wm/OOboKKtXlGAKL5CHC3KT87z8GpSfikVEfpMXfd/3zG5Q8FvsmcLjL9nnxCVb5CV2/9ghlZrvPknb6kKgUta/1y8ha6h7E9w23fIscjpHLD3TSP2JtigpfFPPv6MjeMaZMkHiuBQdJH7NVuOUM0OBRUsL+K5hsWReoqXqtPGRfAG4GUk6DP2yTwPSjv4dXWin+L5iYBxzgV8A0L+hJssrjUAo/gznMflKFw8xkcQ3UK0moMxSVzHeq/SRIowYfx9by1IJr8yRc1KqEHK+2lPApIMQBXn12Pnz/4ik+NkfOC7/Mk4QT718+SSzQmnJAq4sckh/k3lecxn3fW5T15LwjKiZFrxdXWclnuc0nMUlbQL8xL4Fwkz3bELTCwylECrugYvoHIhkaQx7/nLWO8To6zImWRTN9O6ietHiH3q5BnjDc4M59N8BeCZWIbYU+cJH8UDI596BZRfKo16WJXjguMDz3rJDOqEW/RjxYH90QdHTrxZlktVH5hKpTqKnNAXaUiB6I1+P6E2h7z3gGIgcXG6+rmpxzIpTxXF3I87MBz/wZpZQarBpGeMSXuOGvkVUvaxPiT9q7OxFWDv4Y79lYAlxKbsrgRlQDxJ8VhHmaX7E28EKk+c1h9lPREq2w2/bBQ/N5XrwLnf4K6yWAPLuyvQZYDJH4DunEyP+JKVZwUjxsu4MkvnwucdsM/1hX4Ttgc=");
String decrypted =
aesDecryptMessage(encryptedMessage,rsaDecryptedBase64EncodedSecretKey1,base64EncodedIVBytes);
System.out.println("Decrypted: "+decrypted);
This works well if I run it as Java program. But fails to work when I call
the rest webservice in TomEE. I checked by verifying the message,secretkey
and iv bytes. Everything looks ok.
--
View this message in context:
http://tomee-openejb.979440.n4.nabble.com/RSA-encryption-does-not-looks-to-be-working-tp4680268.html
Sent from the TomEE Users mailing list archive at Nabble.com.