IllegalBLockSizeException when decrypting - java

I wrote an encrypt and a decrypt function. The encrypt works fine, but I always get IllegalBlockSizeException in the decrypt.
public static String aes_encrypt (String text, String key)
{
SecretKey skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipher.init(Cipher.ENCRYPT_MODE, skey);
return new String((cipher.doFinal(text.getBytes())));
}
And here's the decrypt function:
public static String aes_decrypt (String text, String key)
{
SecretKey skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
cipher.init(Cipher.DECRYPT_MODE, skey);
return new String((cipher.doFinal(text.getBytes())));
}
Here's the simple main method that tests this:
public static void main (String args[])
{
String text = "Hello, world!";
String key = "nv93h50sk1zh508v";
String en, de;
System.out.println("Text: " + text);
System.out.println("Encrypted: " + (en = aes_encrypt(text, key))
+ " length = " + en.length());
System.out.println("Decrypted: " + (de = aes_decrypt(en, key)));
}
Does anyone know how to "pad" the encrypted string properly so that I can decrypt it?
(I tried padding the string with 0 until the length is a multiple of 16, but got something like string not properly padded.)
Thanks

I think the problem is in your using the String constructor. This is converting to string using a text encoding mechanism, which may not preserve every value in the byte array - unsupported ones in the system default encoding may be discarded, leaving the encoded data shorter than it should be. If you want a string representation, convert to hex or base 64 encoding instead. And reverse whatever encoding you use here at the start of the decryption method.
It's not a padding issue - the encryption call will pad this fine, you are short of bytes because of your means of encoding the byte array to a string.
You'll find some base 64 instructions in answers to this SO question.

Related

Issue with key and iv on AES 256-CBC

I get a encrypted base64 string from Python.
The format is AES 256 CBC, but when I try to decrypt using Android it return decrypted string as nil.
Python
# coding=utf-8
import base64
from random import choice
from string import letters
try:
from Crypto import Random
from Crypto.Cipher import AES
except ImportError:
import crypto
import sys
sys.modules['Crypto'] = crypto
from crypto.Cipher import AES
from crypto import Random
class AESCipher(object):
def __init__(self, key):
self.bs = 32
self.key = key
def encrypt(self, raw):
_raw = raw
raw = self._pad(raw)
print raw, ';'
print _raw, ';'
iv = "".join([choice(letters[:26]) for i in xrange(16)])
print " iv :", iv
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))
def decrypt(self, enc):
enc = base64.b64decode(enc)
iv = enc[:AES.block_size]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
def _pad(self, s):
a = (self.bs - len(s) % self.bs)
b = chr(self.bs - len(s) % self.bs)
return s + a * b
#staticmethod
def _unpad(s):
return s[:-ord(s[len(s) - 1:])]
def encrypt(k, t):
o = AESCipher(k)
return o.encrypt(t)
def decrypt(k, t):
o = AESCipher(k)
return o.decrypt(t)
def main():
k = "qwertyuiopasdfghjklzxcvbnmqwerty"
s1 = "Hello World!"
d2 = encrypt(k, s1)
print " Password :", k
print "Encrypted :", d2
print " Plain :", decrypt(k, d2)
if __name__ == '__main__':
main()
Java
Here I use https://github.com/fukata/AES-256-CBC-Example
final String aEcodedSting = "aWVnZWphbnBleWJlemdteeAal+cw04QPYRuuIC3J1/zbkZZSCqxGLo/a26ZiieOk";
String decrypted = AESUtil.decrypt(aEcodedSting);
When I try to decrypt I got this
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.vinu.aessamble/com.example.vinu.aessamble.MainActivity}:
java.lang.RuntimeException: javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT
This is the Python encryption output:
Password : qwertyuiopasdfghjklzxcvbnmqwerty
Encrypted : aWVnZWphbnBleWJlemdteeAal+cw04QPYRuuIC3J1/zbkZZSCqxGLo/a26ZiieOk
iv : iegejanpeybezgmy
plainText : ser456&*(
Please notify me when anyone can solve this using another library.
There are 4 problems:
Difference between python output and java input
Different IV and key
Different key creation
Padding
1) Currently your python code output is a base64 encoding of iv + encrypted_data
return base64.b64encode(iv + cipher.encrypt(raw))
But in java you're directly decrypting raw data.
You should fix this way
// Decode base64
byte[] array = Base64.decode(src);
// Get only encrypted data (removing first 16 byte, namely the IV)
byte[] encrypted = Arrays.copyOfRange(array, 16, array.length);
// Decrypt data
decrypted = new String(cipher.doFinal(encrypted));
2) You must use same IV and key for input and output, so you should copy them from python console output:
iv : qbmocwtttkttpqvv
Password : qwertyuiopasdfghjklzxcvbnmqwerty
Encrypted : anZxZHVpaWJpb2FhaWdqaCK0Un7H9J4UlXRizOJ7s8lchAWAPdH4GRf5tLAkCmm6
Plain : Hello World!
and paste in java code:
private static final String ENCRYPTION_KEY = "qwertyuiopasdfghjklzxcvbnmqwerty";
private static final String ENCRYPTION_IV = "qbmocwtttkttpqvv";
3) In python you're using the key as string, but in java library it is hashed before being used for decrypting, so you should change your makeKey() method:
static Key makeKey() {
try {
byte[] key = ENCRYPTION_KEY.getBytes("UTF-8");
return new SecretKeySpec(key, "AES");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
4) Finally, you don't need to specify a padding in java with "AES/CBC/PKCS5Padding", because this way you force Cipher to pad automatically.
You can simply use "AES/CBC/NoPadding" in your decrypt() method, so it should look like this:
public static String decrypt(String src) {
String decrypted = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
byte[] array = Base64.decode(src);
byte[] encrypted = Arrays.copyOfRange(array, 16, array.length);
decrypted = new String(cipher.doFinal(encrypted));
} catch (Exception e) {
throw new RuntimeException(e);
}
return decrypted;
}
Java output with your base64 and IV:
encrypted: aWVnZWphbnBleWJlemdteeAal+cw04QPYRuuIC3J1/zbkZZSCqxGLo/a26ZiieOk
decrypted: ser456&*(
Edit:
As suggested by Artjom B. (thank you), it would be better to read IV directly from ciphertext instead of hardcoding in AESUtil.
Your input consists of the IV in first 16 bytes and encrypted text in last 16 bytes, so you could take advantage of this.
public static String decrypt(String src) {
String decrypted = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
// Decode input
byte[] array = Base64.decode(src);
// Read first 16 bytes (IV data)
byte[] ivData = Arrays.copyOfRange(array, 0, 16);
// Read last 16 bytes (encrypted text)
byte[] encrypted = Arrays.copyOfRange(array, 16, array.length);
// Init the cipher with decrypt mode, key, and IV bytes array (no more hardcoded)
cipher.init(Cipher.DECRYPT_MODE, makeKey(), new IvParameterSpec(ivData));
// Decrypt same old way
decrypted = new String(cipher.doFinal(encrypted));
} catch (Exception e) {
throw new RuntimeException(e);
}
return decrypted;
}
Moreover, as said here
Python code uses a 32 byte block size for padding which means that Java will still not be able to decrypt half of all possible ciphertexts. AES block size is 16 bytes and this should be changed in the Python implementation
You could change your Python class as below (AES.block_size is equal to 16):
class AESCipher(object):
def __init__(self, key):
self.bs = AES.block_size
self.key = key

Java AES Counter Mode Incrementing

I've written a an encryption/decryption prototype with Java using sample code in this answer. However, I'm trying to play with AES' counter mode (CTR) and the encrypted values appear to be just as incrementable as the integer sequence that I'm trying to encrypt.
Consider the following output of my prototype:
i = 0: enc='5941F8', dec='000', length=6
i = 1: enc='5941F9', dec='001', length=6
i = 2: enc='5941FA', dec='002', length=6
i = 3: enc='5941FB', dec='003', length=6
i = 4: enc='5941FC', dec='004', length=6
i = 5: enc='5941FD', dec='005', length=6
i = 6: enc='5941FE', dec='006', length=6
i = 7: enc='5941FF', dec='007', length=6
i = 8: enc='5941F0', dec='008', length=6
i = 9: enc='5941F1', dec='009', length=6
i = 10: enc='5940F8', dec='010', length=6
i = 11: enc='5940F9', dec='011', length=6
i = 12: enc='5940FA', dec='012', length=6
Notice how the enc values usually only differ from the dec values by a single digit. Are encrypted values generated by AES' counter mode usually this iterable/similar to each other or am I doing something wrong?
So far, I have tried playing with different encryption keys, init vectors, padding schemes, longer/shorter integer sequences (starting from different values) etc. but nothing seems to work so far. Also, Google and other SO questions on the Java AES Cipher in Counter Mode have been of little use so far. Please bear in mind also that I'm a crypto newbie.
Code for my prototype is as follows:
public class Encryptor {
public static String encrypt(String key, String initVector, String value) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes());
return DatatypeConverter.printHexBinary(encrypted);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static String decrypt(String key, String initVector, String encrypted) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = cipher.doFinal(DatatypeConverter.parseHexBinary(encrypted));
return new String(decrypted);
}
catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key = "Bar12345Bar12345"; // 128 bit key
String initVector = "RandomInitVector"; // 16 bytes IV
System.out.println(decrypt(key, initVector,
encrypt(key, initVector, "Hello World")));
for (int i = 0; i < 1000; ++i) {
String encrypted = encrypt(key, initVector, StringUtils.leftPad("" + i, 3, '0'));
String decrypted = decrypt(key, initVector, encrypted);
int encLen = encrypted.length();
System.out.println("i = " + i + ": enc='" + encrypted + "', dec='" + decrypted + "', length=" + encLen);
}
}
}
CTR mode is a streaming mode of operation. It means that a nonce and key pair creates a unique key stream which is then XORed with the plaintext. Since, XOR is symmetric, the exact same operation is applied to decrypt the ciphertext.
Now, XOR work bit-wise. If you use the same key and nonce pair for multiple encryptions, you will encrypt the plaintext with the exact same key stream every time. This means that the bit positions that are different between two plaintext will also be different when comparing the two resulting ciphertexts. This is called the two-time pad or the many-time pad.
In your example, if you XOR enc and dec for each iteration, you will always get 0x6971C8. Those are the first three bytes of the key stream. The ASCII character 0 is 0x30 which when XORed with 0x59 is 0x69 and so on.
The solution would be to use a different nonce (number used once) every time you encrypt with the same key. The nonce (sometimes called IV) is supposed to be smaller than the block size of the underlying block cipher. AES has a block size of 16 bytes. We generally choose random nonces with a length of 8 bytes or 12 bytes depending on how much data we want to encryption without a counter collision. A 12 byte nonce seems like the best compromise, because you can generate many random nonces without much of a chance of a collision and you can encrypt up to 68 GB with a key+nonce pair without a chance of a counter collision.

Part of Decrypt non-sense

I am working a chat in android, here I am using the next methods for key generation, encrypt and decrypt messages. The problem is that when I send a message for example "hola" in the other side I get "holgAAAAAAAAAAAAAAA". Could you help to fix this?.
private byte[] K;
public void setK(){
KeyGenerator KeyGen=KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey key=KeyGen.generateKey();
K = key.getEncoded();
}
public String encrypt(byte[] input){
try {
IvParameterSpec iv = new IvParameterSpec(Base64.decode("Hola".getBytes(), Base64.DEFAULT));
SecretKeySpec key = new SecretKeySpec(K, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
return Base64.encodeToString(cipherText, Base64.DEFAULT);
} catch (Exception e) {
Log.e(JUAN, "failed to encrypt ", e);
}
return null;
}
public String decrypt(byte[] input){
try {
IvParameterSpec iv = new IvParameterSpec(Base64.decode("Hola".getBytes(), Base64.DEFAULT));
SecretKeySpec key = new SecretKeySpec(K, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, plainText, 0);
ctLength += cipher.doFinal(plainText, ctLength);
return Base64.encodeToString(plainText, Base64.DEFAULT);
} catch (Exception e) {
Log.e(JUAN, "failed to decrypt ", e);
}
return null;
}
EDIT
Here is my calling, for example to encrypt "Hola".
encrypt(Base64.decode("Hola".getBytes(), Base64.DEFAULT));
decrypt(Base64.decode(ciphertext, Base64.DEFAULT));
There are multiple problems with your code:
Your input and output types of the decryption function are reversed. If you encrypt a byte[], you should get one out when you decrypt it. If your ciphertext is a Base64 String then the decryption method should take such a String and not a byte[].
String encrypt(byte[] plaintext) {
...
return Base64.encodeToString(cipher.doFinal(plaintext), Base64.DEFAULT);
}
byte[] encrypt(String ciphertext) {
...
return cipher.doFinal(Base64.decode(ciphertext.getBytes("UTF-8"), Base64.DEFAULT));
}
You're passing a single plaintext and ciphertext into their respective method, but then use cipher.update() and cipher.doFinal(). This is not necessary. You should use a single cipher.doFinal() call without a previous buffer. Encryption example:
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal(plaintext);
Since "Hola" is supposed to be what the user typed in, it doesn't make any sense to decode from Base 64. Not all strings that someone types in are valid Base 64 encoded so that they can be decoded. You shouldn't decode the input at all, but pass it directly into the encrypt() function.
Using String#getBytes() is unsafe, because it uses the default Charset of the system. The decryption might not succeed when a different default Charset is used on the receiving system. You should specify the Charset yourself and get the String from the byte[] after decryption:
String ciphertext = encrypt(plaintext.getBytes("UTF-8"));
String recoveredPlaintext = new String(decrypt(ciphertext), "UTF-8");
You're not using your static IV.
Security Issues:
You're using ECB mode. Don't do this! It's not semantically secure. Use at least CBC mode with a random IV. The IV doesn't have to be hidden, so you can simply prepend it to the ciphertext.
You're not authenticating the ciphertext. Your system might be vulnerable to the padding oracle attack. You should either use an encrypt-then-MAC approach with a strong MAC like HMAC-SHA256 or use an authenticated mode of operation for AES like GCM or EAX.
Use for example this library by Isaac Potoczny-Jones of which is compatible with Android. It supports AES-CBC with a random IV and ciphertext authentication with HMAC-SHA256.
Your code is OK assuming that the parameter input in your public String decrypt(byte[] input) method is successfully Base64 decoded from the cipher text by the caller (because your encrption returns Base64 encoded cipher string). But, in the decrypt() method you are creating a byte array plainText by getOutputSize() method. That makes plainText an array of size of multiple of AES Block Size(16). For your case, plainText is a 16 byte array. So after decrypting and removing the paddings from cipher text the plainText contains the decrypted text with some zeroes, those zeroes are then encoded into AAA...As.
So use
return Base64.encodeToString(plainText, 0, ctLength, Base64.DEFAULT);
instead of
return Base64.encodeToString(plainText, Base64.DEFAULT);
Note: You are using ECB mode, so your IvParameterSpec is useless. Use CBC mode instead.
Edition: Your calling is not OK. Try this
//Encryption side
String text = "hola, hi, anything u want";
byte[] plainText = text.getBytes("UTF-8");
String base64 = encrypt(plainText);
// Decryption side
byte[] cipherText = Base64.decode(base64, Base64.DEFAULT);
String plainEncodedText = decrypt(cipherText);
byte[] plainTextAsByte = Base64.decode(plainEncodedText, Base64.DEFAULT);
String plainTextAgain = new String(plainTextAsByte , "UTF-8");
Now print the plainTextAgain and hope this will work!

Java PBEwithMD5andDES decryption issue

I have an encryption method that works well and passes me an encrypted String.
KeySpec keySpec = new PBEKeySpec(encryptionPassword.toCharArray(), salt, iterations);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterations);
//encryption
Cipher encoder = Cipher.getInstance(key.getAlgorithm());
encoder.init(Cipher.ENCRYPT_MODE, key, paramSpec);
String str_to_encrypt = "Hello";
byte[] enc = encoder.doFinal(str_to_encrypt.getBytes("UTF8"));
System.out.println("encrypted = " + DatatypeConverter.printBase64Binary(enc));
output: encrypted = vjXsSX0cBNc=
However I also wish to Decrypt this String I've recieved, I am having trouble with this however, especially the reverse of getBytes and printBase64Binary.
This is the first time I have attempted to decrypt, so I used a lot of Googling, I found that 'parseBase64Binary' could get bytes from a string, with 'new String(dec, "US-ASCII") then turning the bytes into a string...somewhere something went askew.
//decryption
Cipher encoder = Cipher.getInstance(key.getAlgorithm());
encoder.init(Cipher.DECRYPT_MODE, key, paramSpec);
String str_to_decrypt = "vjXsSX0cBNc=";
byte[] dec = DatatypeConverter.parseBase64Binary(str_to_decrypt);
System.out.println("decrypted = " + new String(dec, "UTF8"));
output: decrypted = ?5?I}?
The only thing I can think of is that I haven't actually decrypted the string properly, as I have not used encoder.doFinal anywhere... somewhat stumped as to where to use it.
EDIT: Answered own question for completeness, all sorted!
Played around a bit more, I was right in saying I hadn't properly decrypted the String as I hadn't used encoder.doFinal... trial and error led me to this:
String str_to_decrypt = "vjXsSX0cBNc=";
byte[] dec = encoder.doFinal(DatatypeConverter.parseBase64Binary(str_to_decrypt));
System.out.println("decrypted = " + new String(dec, "UTF8"));
output: decrypted = Hello

Why doesn't this simple AES encryption work?

Why does not this AES encryption work? I've written it in Java to test, but I am not able to decrypt. I get garbage upon decryption. Why? Its so simple - In the main method, print plain text, encrypt, print cipher text, decrypt, print plain text again. Am I doing something wrong? Please help me figure out the problem.
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESTest {
public static void main(String [] args) {
try {
String plainText = "Hello World!!!!!";
String encryptionKey = "E072EDF9534053A0B6C581C58FBF25CC";
System.out.println("Before encryption - " + plainText);
String cipherText = encrypt(plainText, encryptionKey);
System.out.println("After encryption - " + cipherText);
String decrypted = decrypt(cipherText, encryptionKey);
System.out.println("After decryption - " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String plainText, String passkey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(hexStringToByteArray(passkey), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
String cipherText = new String(cipher.doFinal(plainText.getBytes()));
return cipherText;
}
public static String decrypt(String cipherText, String passkey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(hexStringToByteArray(passkey), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
String plainText = new String(cipher.doFinal(cipherText.getBytes()));
return plainText;
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}
The output of the cipher is a sequence of random-looking bytes. You have no guarantee that these bytes will be a valid encoding for a character string in whatever is your system's default encoding. So this line:
String cipherText = new String(cipher.doFinal(.....));
is likely to lose information that you'll need for decryption.
Therefore you will not get the right bytes reconstructed in your decrypt operation. For example, if your default encoding is UTF-8, it is overwhelmingly unlikely that the correct ciphertext is something that String.getBytes() is even able to produce.
Two things:
No padding can only work if you use input that is an exact mulitple of your key size, which is 128 bit or 16 bytes. So in your particular case "Hello World!!!!!".getBytes() is actually a multiple of 16, but this is of course not true for arbitrary Strings.
Use "AES/CBC/PKCS5Padding" instead to solve this issue.
Do not turn your encrypted data into a String - this will and change the encrypted output. There's no guarantee that new String(byte[]).getBytes() returns the exact same byte array!
So you should leave the encrypted data as what it is - a stream of bytes. Thus encrypt should return byte[] instead and decrypt should take byte[] as input - this is a working example:
public class NewClass {
public static void main(String [] args) {
try {
String plainText = "Hello World!!!!";
String encryptionKey = "E072EDF9534053A0B6C581C58FBF25CC";
System.out.println("Before encryption - " + plainText);
byte[] cipherText = encrypt(plainText, encryptionKey);
System.out.println("After encryption - " + cipherText);
String decrypted = decrypt(cipherText, encryptionKey);
// -> Hello World!!!!
System.out.println("After decryption - " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] encrypt(String plainText, String passkey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(hexStringToByteArray(passkey), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
return cipher.doFinal(plainText.getBytes());
}
public static String decrypt(byte[] cipherText, String passkey) throws Exception{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(hexStringToByteArray(passkey), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
return new String(cipher.doFinal(cipherText));
}
You need to create the SecretKeySpec object once and use it for both encrypt and decrypt. Currently the code is creating two different keys for each operation and this will definitely lead to incorrect results.

Categories

Resources