I am trying to encrypt and decrypt an image using the Facebook library. This is the first time I use it and therefore carry it with me if it is trivial. I looked at other questions about SO to find out the reasons for my exceptions, but I couldn't get it to work.
Here is what I have done so far ...
Integration: I use Eclipse and therefore downloaded crypto.jar and libs.zip from here and added the jar file to the libs folder and .so to the corresponding folder inside the libs folder.
My scenario:
I need to capture an image from the camera, encrypt and save it in the phone. Decipher it and show it as an image. At a later stage, I also need to decrypt this image from memory and send it over the network.
So my code goes below ...
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (Const.DEBUGGING) { Log.d(Const.DEBUG, "RequestCode: " + requestCode + "\nResultCode:" + resultCode); } int tag = getRecordCount(); tag++; if (requestCode == KTP_PICTURE_REQUEST_CODE) { if (resultCode == RESULT_OK) { ENCRYPTEDFILENAME = tag + "_" + KTP_TAG + ".png"; saveFile((Bitmap) data.getExtras().get("data"), requestCode); Bitmap decryptedImage = decodeFile(ENCRYPTEDFILENAME); mImgBtnKtppicture.setImageBitmap(decryptedImage); } else if (resultCode == RESULT_CANCELED) { if (Const.DEBUGGING) Log.d(Const.DEBUG, "KTP_RESULT CANCELED"); } else { } } if (requestCode == PROFILE_PICTURE_REQUEST_CODE) { if (resultCode == RESULT_OK) { ENCRYPTEDFILENAME = tag + "_" + PROFILE_TAG + ".png"; saveFile((Bitmap) data.getExtras().get("data"), requestCode); Bitmap decryptedImage = decodeFile(ENCRYPTEDFILENAME); mImgBtnPicture.setImageBitmap(decryptedImage); } else if (resultCode == RESULT_CANCELED) { if (Const.DEBUGGING) Log.d(Const.DEBUG, "PICTURE_RESULT CANCELED"); } else { } } }
SaveFile ():
public void saveFile(Bitmap photo, int code) { try { ContextWrapper cw = new ContextWrapper(getApplicationContext()); File directory = cw.getDir(DIRECTORY, Context.MODE_PRIVATE); File mypath = new File(directory, ENCRYPTEDFILENAME); if (code == KTP_PICTURE_REQUEST_CODE) { mKtppicture = Uri.fromFile(mypath).toString(); if (Const.DEBUGGING) Log.d(Const.DEBUG, "KTP Picture Path: " + mKtppicture); } else if (code == PROFILE_PICTURE_REQUEST_CODE) { mPicture = Uri.fromFile(mypath).toString(); if (Const.DEBUGGING) Log.d(Const.DEBUG, "Profile Picture Path: " + mPicture); } Crypto crypto = new Crypto( new SharedPrefsBackedKeyChain(this), new SystemNativeCryptoLibrary()); if (!crypto.isAvailable()) { return; } OutputStream fileStream = new BufferedOutputStream( new FileOutputStream(mypath)); OutputStream outputStream = crypto.getCipherOutputStream( fileStream, new Entity("Password")); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.write(bitmapToBytes(photo)); objectOutputStream.close();
bitmapToBytes ():
private byte[] bitmapToBytes(Bitmap photo) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] byteArray = stream.toByteArray(); return byteArray; }
decodeFile ():
private Bitmap decodeFile(String filename) { Crypto crypto = new Crypto( new SharedPrefsBackedKeyChain(this), new SystemNativeCryptoLibrary()); ContextWrapper cw = new ContextWrapper(getApplicationContext()); File directory = cw.getDir(DIRECTORY, Context.MODE_PRIVATE); File file = new File(directory, filename); try{ FileInputStream fileStream = new FileInputStream(file); InputStream inputStream = crypto.getCipherInputStream( fileStream, new Entity("Password")); ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); Bitmap bitmap = bytesToBitmap((byte[])objectInputStream.readObject()); return bitmap; }catch (Exception e) { e.printStackTrace(); } return null; }
bytesToBitmap ():
private Bitmap bytesToBitmap(byte[] bytes) { Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); return bitmap; }
When I try to save the image, I get a UnsupportedOperationException in objectOutputStream.close(); in saveFile ()
Logcat Trail:
10-01 16:55:34.529: W/System.err(31291): java.lang.UnsupportedOperationException 10-01 16:55:34.529: W/System.err(31291): at com.facebook.crypto.streams.NativeGCMCipherOutputStream.write(NativeGCMCipherOutputStream.java:93) 10-01 16:55:34.529: W/System.err(31291): at java.io.DataOutputStream.writeByte(DataOutputStream.java:144) 10-01 16:55:34.529: W/System.err(31291): at java.io.ObjectOutputStream.drain(ObjectOutputStream.java:394) 10-01 16:55:34.529: W/System.err(31291): at java.io.ObjectOutputStream.flush(ObjectOutputStream.java:461) 10-01 16:55:34.529: W/System.err(31291): at java.io.ObjectOutputStream.close(ObjectOutputStream.java:337) 10-01 16:55:34.529: W/System.err(31291): at com.xx.xxx.RegistrationActivity.saveFile(RegistrationActivity.java:761) 10-01 16:55:34.529: W/System.err(31291): at com.xx.xxx.RegistrationActivity.onActivityResult(RegistrationActivity.java:639) 10-01 16:55:34.529: W/System.err(31291): at android.app.Activity.dispatchActivityResult(Activity.java:5423) 10-01 16:55:34.529: W/System.err(31291): at android.app.ActivityThread.deliverResults(ActivityThread.java:3347) 10-01 16:55:34.529: W/System.err(31291): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394) 10-01 16:55:34.529: W/System.err(31291): at android.app.ActivityThread.access$1300(ActivityThread.java:135) 10-01 16:55:34.529: W/System.err(31291): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244) 10-01 16:55:34.529: W/System.err(31291): at android.os.Handler.dispatchMessage(Handler.java:102) 10-01 16:55:34.529: W/System.err(31291): at android.os.Looper.loop(Looper.java:136) 10-01 16:55:34.529: W/System.err(31291): at android.app.ActivityThread.main(ActivityThread.java:5001) 10-01 16:55:34.529: W/System.err(31291): at java.lang.reflect.Method.invokeNative(Native Method) 10-01 16:55:34.529: W/System.err(31291): at java.lang.reflect.Method.invoke(Method.java:515) 10-01 16:55:34.529: W/System.err(31291): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 10-01 16:55:34.529: W/System.err(31291): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 10-01 16:55:34.529: W/System.err(31291): at dalvik.system.NativeStart.main(Native Method) 10-01 16:55:34.529: W/System.err(31291): java.io.IOException: Unexpected crypto version -1 10-01 16:55:34.529: W/System.err(31291): at com.facebook.crypto.util.Assertions.checkArgumentForIO(Assertions.java:29) 10-01 16:55:34.539: W/System.err(31291): at com.facebook.crypto.CipherHelper.getCipherInputStream(CipherHelper.java:52) 10-01 16:55:34.539: W/System.err(31291): at com.facebook.crypto.Crypto.getCipherInputStream(Crypto.java:83) 10-01 16:55:34.539: W/System.err(31291): at com.xx.xxx.RegistrationActivity.decodeFile(RegistrationActivity.java:821) 10-01 16:55:34.539: W/System.err(31291): at com.xx.xxx.RegistrationActivity.onActivityResult(RegistrationActivity.java:640) 10-01 16:55:34.539: W/System.err(31291): at android.app.Activity.dispatchActivityResult(Activity.java:5423) 10-01 16:55:34.539: W/System.err(31291): at android.app.ActivityThread.deliverResults(ActivityThread.java:3347) 10-01 16:55:34.539: W/System.err(31291): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3394) 10-01 16:55:34.539: W/System.err(31291): at android.app.ActivityThread.access$1300(ActivityThread.java:135) 10-01 16:55:34.539: W/System.err(31291): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244) 10-01 16:55:34.539: W/System.err(31291): at android.os.Handler.dispatchMessage(Handler.java:102) 10-01 16:55:34.539: W/System.err(31291): at android.os.Looper.loop(Looper.java:136) 10-01 16:55:34.539: W/System.err(31291): at android.app.ActivityThread.main(ActivityThread.java:5001) 10-01 16:55:34.539: W/System.err(31291): at java.lang.reflect.Method.invokeNative(Native Method) 10-01 16:55:34.539: W/System.err(31291): at java.lang.reflect.Method.invoke(Method.java:515) 10-01 16:55:34.539: W/System.err(31291): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 10-01 16:55:34.549: W/System.err(31291): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 10-01 16:55:34.549: W/System.err(31291): at dalvik.system.NativeStart.main(Native Method) 10-01 16:55:34.549: D/BAT(31291): onResume called
Thanks for your help...