EDIT ::: The code in the question works, but it takes around 10 seconds for getting back to the activity once the image is taken in camera. I gave up this approach and used Facebook's Conceal Library to encrypt and decrypt images. Link to Facebook's Solution : Facebook Conceal - Image Encryption and Decryption
I have looked at lot of examples, but still couldn't figure out a way to get Encryption and Decryption right. I thought i got it correct when I used some random code on the internet, but while decoding, i get a BadPadding Exception.
So, i am trying to work it out. I am following the below question, as suggested by most people on SO (but this code shows how to encrypt a string). Can some one help me out in encrypting and decrypting the image? Will the code in the question work for images?
Link to the question : Java 256-bit AES Password-Based Encryption
Here is what i have done till now:
//Global arraylist to store iv and cipher
static ArrayList<byte[]> ivandcipher = new ArrayList<byte[]>();
//Generating Key
public static SecretKey generateKey() throws NoSuchAlgorithmException {
char[] password = { 'a', 'b', 'c', 'd', 'e' };
byte[] salt = { 1, 2, 3, 4, 5 };
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = null;
try {
tmp = factory.generateSecret(spec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
yourKey = new SecretKeySpec(tmp.getEncoded(), "AES");
return yourKey;
}
//Encoding File
//byte[] fileData, contains the bitmap(image) converted to byte[]
public static ArrayList<byte[]> encodeFile(SecretKey yourKey, byte[] fileData)
throws Exception {
byte[] encrypted = null;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, yourKey);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
encrypted = cipher.doFinal(fileData);
ivandcipher.clear();
ivandcipher.add(iv);
ivandcipher.add(encrypted);
return ivandcipher;
}
Why am i adding iv and encrypted byte[]s to ivandcipher. Because, as the answer in the link suggests, that i should be using the same iv while decryption.
//Decode file
//I call a overloaded decodeFile method inside this method.. please note
private Bitmap decodeFile(String filename) {
try {
yourKey = generateKey();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
try {
byte[] decodedData = decodeFile(yourKey, readFile(filename));
Bitmap bitmap = bytesToBitmap(decodedData);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//overloaded decodeFile method
public static byte[] decodeFile(SecretKey yourKey, byte[] fileData)
throws Exception {
byte[] decrypted = null;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, yourKey, new IvParameterSpec(ivandcipher.get(0)));
decrypted = cipher.doFinal(fileData);
return decrypted;
}
I guess the problem is with the fileData[], that i am not able to encrypt and decrypt correctly. For Strings as shown in the answer of the above link, i.e.,
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
what should be given as parameter for cipher.doFinal()?
Let me know if you need any other piece of code.