tldr: generated rsa key pair using node-forge, encrypted hello and converted it to base64 in order to decrypt it using the same key pair (imported using pem files) in java but it throws an exception while the key pair is working fine with data encrypted by java
I am generating a key pair in node which works fine for decrypting and encrypting in both java and node, but I am unable to decrypt the encrypted value from node in java
the key pair is generated using the following nodejs code
var bip39 = require("bip39");
var forge = require("node-forge");
async function test() {
var mnemonic = "fever draw mind boil renew fire sleep palace useful ritual wood snake april polar brown off round zebra swallow health grass drink jelly beef";
console.log(mnemonic)
let seed = await bip39.mnemonicToSeed(mnemonic);
console.log(seed.toString("hex"))
const prng = forge.random.createInstance();
prng.seedFileSync = () => seed
const {
privateKey,
publicKey
} = forge.pki.rsa.generateKeyPair({
bits: 1024,
prng,
workers: 2
})
console.log(await forge.pki.publicKeyToRSAPublicKeyPem(publicKey));
console.log(await forge.pki.privateKeyToPem(privateKey));
let encrypted = publicKey.encrypt("hello");
var previousBase ="WTq03NoOtGHX+Xs1Mu6bbQmjQ+xSssj2mSeRf55+lw/tVaGRTI7KQZzu8DFqNJS4kzu6iJjqKTmnvtAMzPOo4KAmEtZAMDEZw7D1Y5ptb0cDP0SgROsZgZr5XpGbifQMDGT+rZr/5EfFOXdwDvUy1rUABAKpSbXFZTF64UFM4lk=";
var previous = atob(previousBase);
let base = btoa(encrypted);
console.log(base);
var x = new TextEncoder().encode(previousBase);
var all = "";
for (var i = 0; i < x.length; i++) {
all += x[i] + ", ";
}
console.log(all.substring(0, all.length - 2))
console.log(await privateKey.decrypt(previous));
console.log(await privateKey.decrypt(encrypted));
};
test();
since I am trying to decrypt/encrypt using the same private/public key in Java I decided to add a few logs so I have a base to work with
fever draw mind boil renew fire sleep palace useful ritual wood snake april polar brown off round zebra swallow health grass drink jelly beef
8f445e53ea42708dd4be30c646261c9fc3352125c42f8f5ead86d44c15adbac4a46ffe1dca758f99bf46c7b939fd3db0f2f3000b792bc9192156e5ef5936a732
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAK0HXXtavoJkYXYSBFvb+JINZ9MFZANLWRVOu69iiP6PgILqEbV8ybFm
vdSCuZu0BB/P5f0uW/0fw0149UZxXltrkPZHqYLPckXOxgRD3LAWbI+vwV0UqU0X
597hg5E8UnV+2S5VG4/QxpAS5iiAPwT96dxjxEhZ3mRqLX74BsrDAgMBAAE=
-----END RSA PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCtB117Wr6CZGF2EgRb2/iSDWfTBWQDS1kVTruvYoj+j4CC6hG1
fMmxZr3UgrmbtAQfz+X9Llv9H8NNePVGcV5ba5D2R6mCz3JFzsYEQ9ywFmyPr8Fd
FKlNF+fe4YORPFJ1ftkuVRuP0MaQEuYogD8E/encY8RIWd5kai1++AbKwwIDAQAB
AoGAFDPb8l8yBz95MbQA1kjkyQjPqo/ikY/motpCh8PVgwN2WdLCppIfaps4Zuus
iEWIhb5ceCdFjlR7FTyeRs9N2OTC2Mcp1n1sxfHNFMGPOsxyMAaIw9UhFzpr2cHy
PXiPbyg+y4EMwEbB2js7Zf2A2wNSda4VBkYUZIkBXIxmUwECQQD9a70jjdfN6Ldj
M6ZqPPg/V5GGsEohfsmsSJKUxzZ3AmFqrwzDmclbfviVmqTiULPDbl4Tb6qvhLc3
Qk//DUijAkEArsosXFv7DkZmMA3MTE8lURgOD509Ts1+4wWIDsbP54pvFoIPX7eG
6NR48SEvjAmZfGgwi6gbwUdBbRFFQwP3YQJAfuPmdZn9V5XR1XM0PXe/2X+QV3+H
7tOcSY6hDqvdIqPngVKbMombYBvofohLTSKZkB6ALn04WuA6GQo0IgJVvwJARvsH
JMKdo2BnYyBXVK3XY6U3IJQkL3o4Cw1WAVovV8HZ9vP+NkqbWLXgH1vwqRfE4saU
4EH2c3jyUs5uqBZWQQJAajdCCVRyPghnfqhzWl68gfvrEATDTWRt4UKY46IP+QUx
islQ2e9ZU+wbjBmqM5zd1oG9yUsxD8c5X0mCyZ1wSg==
-----END RSA PRIVATE KEY-----
HWqv4dvDtLPc8ZhBbTI4JJ89XgxASKacZKuaz+0HF0kInt9R/tDgv2lkNPl7RWC/SNacqY0DnBL1uAQvg8r75nVo7sZ29hhjph5n5ucBNXcT9OSYgGY4fjSmMLvLY3qVSYItSLsIbXrfemWDF2jaV2FbDb4dBCaeC02PjIJQGnw=
87, 84, 113, 48, 51, 78, 111, 79, 116, 71, 72, 88, 43, 88, 115, 49, 77, 117, 54, 98, 98, 81, 109, 106, 81, 43, 120, 83, 115, 115, 106, 50, 109, 83, 101, 82, 102, 53, 53, 43, 108, 119, 47, 116, 86, 97, 71, 82, 84, 73, 55, 75, 81, 90, 122, 117, 56, 68, 70, 113, 78, 74, 83, 52, 107, 122, 117, 54, 105, 74, 106, 113, 75, 84, 109, 110, 118, 116, 65, 77, 122, 80, 79, 111, 52, 75, 65, 109, 69, 116, 90, 65, 77, 68, 69, 90, 119, 55, 68, 49, 89, 53, 112, 116, 98, 48, 99, 68, 80, 48, 83, 103, 82, 79, 115, 90, 103, 90, 114, 53, 88, 112, 71, 98, 105, 102, 81, 77, 68, 71, 84, 43, 114, 90, 114, 47, 53, 69, 102, 70, 79, 88, 100, 119, 68, 118, 85, 121, 49, 114, 85, 65, 66, 65, 75, 112, 83, 98, 88, 70, 90, 84, 70, 54, 52, 85, 70, 77, 52, 108, 107, 61
hello
hello
the first challenge was to actually get the rsa key objects in Java to initialize without any exceptions, which in fact required me to add the dependency
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
now within java I am able to encrypt and decrypt using the keys, but I am unable to decrypt anything that was generated within nodejs as it throws this exception
javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:344)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at Test.main(Test.java:44)
my current code for reference looks like this
import javax.crypto.Cipher;
import javax.xml.bind.DatatypeConverter;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class Test {
static {
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
}
public static void main(String[] args) {
try {
RSAPrivateKey privateKey = parsePrivateKey(Files.readAllBytes(Paths.get("pri.pem")));
RSAPublicKey pub = readPublicKey(new File("pub.pem"));
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, pub);
String test = "hello";
byte[] testBytes = test.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(testBytes);
String base64 = "WTq03NoOtGHX+Xs1Mu6bbQmjQ+xSssj2mSeRf55+lw/tVaGRTI7KQZzu8DFqNJS4kzu6iJjqKTmnvtAMzPOo4KAmEtZAMDEZw7D1Y5ptb0cDP0SgROsZgZr5XpGbifQMDGT+rZr/5EfFOXdwDvUy1rUABAKpSbXFZTF64UFM4lk=";
byte[] decodedBytes = Base64.getDecoder().decode(base64);
String decodedString = new String(decodedBytes);
byte[] secretMessageBytes = decodedString.getBytes(StandardCharsets.UTF_8.name());
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
System.out.println(new String(decryptCipher.doFinal(encryptedMessageBytes)));
byte[] decryptedMessageBytes = decryptCipher.doFinal(secretMessageBytes);
System.out.println(new String(decryptedMessageBytes));
} catch (Exception e) {
e.printStackTrace();
}
}
public static RSAPrivateKey parsePrivateKey(byte[] b) throws InvalidKeySpecException, NoSuchAlgorithmException {
byte[] privateKeyBytes = parseDERFromPEM(b);
return generatePrivateKeyFromDER(privateKeyBytes);
}
public static byte[] parseDERFromPEM(byte[] b) {
return DatatypeConverter.parseBase64Binary(parseKeyData(b));
}
public static String parseKeyData(byte[] b) {
String data = new String(b);
String[] tokens = data.split("-----BEGIN RSA PRIVATE KEY-----");
tokens = tokens[1].split("-----END RSA PRIVATE KEY-----");
return tokens[0];
}
public static RSAPrivateKey generatePrivateKeyFromDER(byte[] b) throws InvalidKeySpecException, NoSuchAlgorithmException {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b);
KeyFactory factory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) factory.generatePrivate(spec);
}
public static RSAPublicKey readPublicKey(File file) throws Exception {
String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
String publicKeyPEM = key
.replace("-----BEGIN PUBLIC KEY-----", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PUBLIC KEY-----", "");
byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
}
}
is it somehow impossible todo what I am trying todo or am I just missing something somewhere since the keys are working with java for encryption and decryption as long as it was encrypted using java.
I believe all data required to replicate my issue is included in this post - if any further information is needed please let me know and I will provide
Encrypted data using modern (computer) ciphers is not text. And the data that can be encrypted can be any bits, not just text, although they are still called 'ciphertext' and 'plaintext' following a historical tradition from past centuries where they actually were text. Neither is other cryptographic data, such as digital signatures, hashes, keys, certificates, and such, although some of them are converted to and from text forms such as (several variants of) base64, hex, and PEM. Your node/forge code represents the RSA-encrypted data in base64, as is common to handle this, but your Java code after decoding the base64 correctly does the following
String decodedString = new String(decodedBytes);
byte[] secretMessageBytes = decodedString.getBytes(StandardCharsets.UTF_8.name());
which tries to treat it as text. This does not work, and turns much of your data into garbage, which also happens to make it longer and trigger the exception you got. You need to use the result of the base64 decoding directly in the decrypt call.
In addition your posted Java code doesn't and can't work on the public-key format you posted. You need to either use forge's publicKeyToPem (which produces the correct 'generic' PUBLIC KEY format -- not RSA PUBLIC KEY) or convert your posted output with something like openssl rsa -RSAPublicKey_in; I did the latter.
Finally, it isn't sufficient to just add Bouncy to the provider list. You must either:
specify the actual provider object in KeyFactory.getInstance
have Bouncy in the list (anywhere) and specify "BC" in KeyFactory.getInstance
put Bouncy at the beginning of the list with insertProviderAt(new org.bouncy...,1)
With those three changes, and some trivial simplification and hardcoded data for convenience, the following gives hello as expected:
String pubbad = "-----BEGIN RSA PUBLIC KEY-----\n"
+"MIGJAoGBAK0HXXtavoJkYXYSBFvb+JINZ9MFZANLWRVOu69iiP6PgILqEbV8ybFm\n"
+"vdSCuZu0BB/P5f0uW/0fw0149UZxXltrkPZHqYLPckXOxgRD3LAWbI+vwV0UqU0X\n"
+"597hg5E8UnV+2S5VG4/QxpAS5iiAPwT96dxjxEhZ3mRqLX74BsrDAgMBAAE=\n"
+"-----END RSA PUBLIC KEY-----\n";
String pubfix = "-----BEGIN PUBLIC KEY-----\n"
+"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtB117Wr6CZGF2EgRb2/iSDWfT\n"
+"BWQDS1kVTruvYoj+j4CC6hG1fMmxZr3UgrmbtAQfz+X9Llv9H8NNePVGcV5ba5D2\n"
+"R6mCz3JFzsYEQ9ywFmyPr8FdFKlNF+fe4YORPFJ1ftkuVRuP0MaQEuYogD8E/enc\n"
+"Y8RIWd5kai1++AbKwwIDAQAB\n"
+"-----END PUBLIC KEY-----\n";
String prvpem = "-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICWwIBAAKBgQCtB117Wr6CZGF2EgRb2/iSDWfTBWQDS1kVTruvYoj+j4CC6hG1\n"
+"fMmxZr3UgrmbtAQfz+X9Llv9H8NNePVGcV5ba5D2R6mCz3JFzsYEQ9ywFmyPr8Fd\n"
+"FKlNF+fe4YORPFJ1ftkuVRuP0MaQEuYogD8E/encY8RIWd5kai1++AbKwwIDAQAB\n"
+"AoGAFDPb8l8yBz95MbQA1kjkyQjPqo/ikY/motpCh8PVgwN2WdLCppIfaps4Zuus\n"
+"iEWIhb5ceCdFjlR7FTyeRs9N2OTC2Mcp1n1sxfHNFMGPOsxyMAaIw9UhFzpr2cHy\n"
+"PXiPbyg+y4EMwEbB2js7Zf2A2wNSda4VBkYUZIkBXIxmUwECQQD9a70jjdfN6Ldj\n"
+"M6ZqPPg/V5GGsEohfsmsSJKUxzZ3AmFqrwzDmclbfviVmqTiULPDbl4Tb6qvhLc3\n"
+"Qk//DUijAkEArsosXFv7DkZmMA3MTE8lURgOD509Ts1+4wWIDsbP54pvFoIPX7eG\n"
+"6NR48SEvjAmZfGgwi6gbwUdBbRFFQwP3YQJAfuPmdZn9V5XR1XM0PXe/2X+QV3+H\n"
+"7tOcSY6hDqvdIqPngVKbMombYBvofohLTSKZkB6ALn04WuA6GQo0IgJVvwJARvsH\n"
+"JMKdo2BnYyBXVK3XY6U3IJQkL3o4Cw1WAVovV8HZ9vP+NkqbWLXgH1vwqRfE4saU\n"
+"4EH2c3jyUs5uqBZWQQJAajdCCVRyPghnfqhzWl68gfvrEATDTWRt4UKY46IP+QUx\n"
+"islQ2e9ZU+wbjBmqM5zd1oG9yUsxD8c5X0mCyZ1wSg==\n"
+"-----END RSA PRIVATE KEY-----\n";
//RSAPrivateKey privateKey = parsePrivateKey(Files.readAllBytes(Paths.get("pri.pem")));
byte[] prvder = Base64.getDecoder().decode( prvpem.replaceAll("-----(BEGIN|END) RSA PRIVATE KEY-----","").replaceAll("\n","") );
RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA","BC") .generatePrivate(new PKCS8EncodedKeySpec(prvder) );
// actually not PKCS8, but BCprov handles this as a special case
//RSAPublicKey pub = readPublicKey(new File("pub.pem"));
byte[] pubder = Base64.getDecoder().decode( pubfix.replaceAll("-----(BEGIN|END) PUBLIC KEY-----","").replaceAll("\n","") );
RSAPublicKey pub = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(pubder) );
String base64 = "WTq03NoOtGHX+Xs1Mu6bbQmjQ+xSssj2mSeRf55+lw/tVaGRTI7KQZzu8DFqNJS4kzu6iJjqKTmnvtAMzPOo4KAmEtZAMDEZw7D1Y5ptb0cDP0SgROsZgZr5XpGbifQMDGT+rZr/5EfFOXdwDvUy1rUABAKpSbXFZTF64UFM4lk=";
byte[] decodedBytes = Base64.getDecoder().decode(base64);
//BAD String decodedString = new String(decodedBytes);
//BAD byte[] secretMessageBytes = decodedString.getBytes(StandardCharsets.UTF_8.name());
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedMessageBytes = decryptCipher.doFinal(decodedBytes);
System.out.println(new String(decryptedMessageBytes));
And merry Xmas, until someone edits this out because Stack is supposed to be impersonal.
I have a problem with encoding a password in java and nodejs.
After I encode the password, I get the same result with javacode and nodejs.
result = [69, 83, 53, 95, -77, -40, -124, 109, 38, -85, 91, -105, 72, -61, 84, 54].
Then I convert it into a buffer in nodejs.
When i use crypto. I have use a method:
const content = 'et'
key = buffer.from(result)
const iv= Buffer.alloc(0)
crypto.createCipheriv("aes-128-ecb", key, iv)
let encrypted = cipher.update(content, "utf8", "base64");
encrypted += cipher.final("base64"); //result: Rrx7BNH5l/miPfFbGgAkMA==
I get a result that is different from the javacode
My java code
String content = 'et'
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] result = cipher.doFinal(content);
system.out.printLn(Base64.encode(encryptResult)) //result:TJ4Z8bGSoJKiRFHwE929mg==
I think This problem occurs when converting the bytes into a buffer. So if array don't have negative number I'll get the correct result.
Please help me any solution
In one of our internal software we're implementing a new API endpoint which must be accessed by external sources through the internet and then it must be secured in some way.
Since we're not allowed to use library as OAuth or public and private keys we choosed javax.crypto AES to crypt out a "custom authorisation token" in each external source by this way:
...
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] applicationIdEncrypted = cipher.doFinal(applicationId.getBytes());
...
The token contains a custom applicationId to identify on the other side who's contacting that endpoint.
Since we must perform an HTTP call, we're converting applicationIdEncrypted into a base64 String
String base64Encoded = Base64.getEncoder().encodeToString(applicationIdEncrypted);
ON THE OTHER SIDE
We're getting the header and decode it from base64
String base64Decoded = new String(Base64.getDecoder().decode(header));
But when attempting to perform the last operation
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
String headerDecoded = new String(cipher.doFinal(base64Decoded.getBytes())); //<- THIS
We got javax.crypto.BadPaddingException: Given final block not properly padded
Both base64Encoded and base64Decoded have the same value in both of the ends.
Attempting to perform the same operation in one of the ends (to not use the HTTP channel) no exception is thrown -but- a different headerDecoded is returned by the new String(cipher.doFinal(base64Decoded.getBytes()));
Looked for the bytes applicationIdEncrypted and base64Decoded.getBytes() and they're slightly different:
applicationIdEncrypted
[-28, -103, 107, 70, -112, 121, 4, -14, -80, -114, -14, 92, -81, -13, -128, 97]
base64Decoded.getBytes()
[-28, -103, 107, 70, 63, 121, 4, -14, -80, -114, -14, 92, -81, -13, -128, 97]
I read that maybe passing from bytes to String could be a loss of informations (maybe?) but I cannot figure it out why of this behaviours since both base64Encoded and base64Decoded have the SAME value in both cases and scenarios.
How can I achieve the passage of a "custom authorisation token" using only Java 1.7 javax.crypto libraries?
EDIT
The "API-KEY" is something like 02E30E6BE24BF1EA
As #James K Polk says, I had a mess with the thousand of String conversion so I managed to have a cleaner code first for a better comprehensive code.
ON THE CLIENT
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] applicationIdEncrypted = cipher.doFinal(applicationId.getBytes());
byte[] base64Encoded = Base64.getEncoder().encode(applicationIdEncrypted);
String out = new String(base64Encoded);
where out is the only one conversion in String and it's the HTTP header's payload.
ON THE OTHER SIDE
byte[] in = out.getBytes();
byte[] base64Decoded = Base64.getDecoder().decode(in);
Key aesKey = new SecretKeySpec("API-KEY".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
byte[] applicationIdDecrypted = cipher.doFinal(base64Decoded);
String applicationId= new String(applicationIdDecrypted);
I had ONLY two conversion into String: out (the header's base64 value) and applicationId.
In this way I used to have the same applicationId value.
I am using following code for encryption in Android project:
SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");
String key = "abcdefg";
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKey _key = kf.generateSecret(keySpec);
String xform = "DES";
Cipher cipher = Cipher.getInstance(xform);
byte[] IV = { 11, 22, 33, 44, 55, 66, 77, 88, 99, 18, 69, 17, 72, 94, 18, 30 };
IvParameterSpec ips = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, _key, ips);
String plainText = "abcdeffdkflsdkf";
byte[] cipherText = cipher.doFinal(plainText.getBytes());
I write this encrypted data in file and I want to decrypt this file in my java project where I am using following code:
SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");
String key = "abcdefg";
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKey _key = kf.generateSecret(keySpec);
String xform = "DES";
Cipher cipher = Cipher.getInstance(xform);
byte[] IV = { 11, 22, 33, 44, 55, 66, 77, 88, 99, 18, 69, 17, 72, 94, 18, 30 };
IvParameterSpec ips = new IvParameterSpec(IV);
cipher.init(Cipher.DECRYPT_MODE, _key, ips);
String cipherText;
//cipher text is read from file.
byte[] plainText = cipher.doFinal(cipherText.getBytes());
But it's not working.
When we do not specify mode of operation(i.e. CBC/ECB) and padding method(i.e. PKCS5Padding/NoPadding) and only algorithm name is specified for getting instance of Cipher then what are the default values which Android and Java use?
Does Android uses CBC by default? As it doesn't give error for IV. If I specify IV in init method and don't specify mode in my java project, it throws exception as IV cannot be used for ECB.
Thanks.
Both Android and Java default to "AES/ECB/PKCS5Padding". Both your key and IV are not of the correct size (so the code should not even run!) and you forget to perform (character) encoding/decoding correctly. Especially the ciphertext should never be directly converted into a string, as unprintable characters are likely to be dropped or converted.