I'm working on android application where I need to save Videos in SD Card which must not be transferable that's why I'm encrypting and decrypting as and when needed with Facebook Conceal
which works perfectly fine if video size is smaller.
Whenever I tries to do encryption and decryption to large video files not more than 10MB
in GenyMotion running 2.3.7
it crashes with OutOfMemoryException
which means I'm running out of heap memory allocated to my application which can't be handled but must be prevented.
Tried :
- Apache Common Utils IO package
- Various IO Utils
Facebook Conceal : Says while decrypting
You must read the entire stream to completion.
The verification is done at the end of the stream.
Thus not reading till the end of the stream will cause
a security bug. For safety, you should not
use any of the data until it's been fully read or throw
away the data if an exception occurs.
Code I'm invoking which encryption and decryption with Facebook Conceal
:
Encryption :
public void startEncryption() {
// Creates a new Crypto object with default implementations of
// a key chain as well as native library.
// Check for whether the crypto functionality is available
// This might fail if android does not load libaries correctly.
if (!crypto.isAvailable()) {
return;
}
OutputStream fileStream;
try {
File mEncryptedFile = new File(mPlainFile.getPath().substring(0,
mPlainFile.getPath().length() - 4)
+ "_encrypted"
+ mPlainFile.getPath().substring(
mPlainFile.getPath().length() - 4,
mPlainFile.getPath().length()));
fileStream = new BufferedOutputStream(new FileOutputStream(
mEncryptedFile));
// Creates an output stream which encrypts the data as
// it is written to it and writes it out to the file.
OutputStream outputStream;
outputStream = crypto.getCipherOutputStream(fileStream, entity);
outputStream.write(FileUtils.readFileToByteArray(mPlainFile));
// fileStream.flush();
// fileStream.close();
// outputStream.flush();
// outputStream.close();
// outputStream.flush();
File mRenameTo = new File(mPlainFile.getPath());
mPlainFile.delete();
mEncryptedFile.renameTo(mRenameTo);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CryptoInitializationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyChainException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Decryption :
public String startDecryption() {
// Get the file to which ciphertext has been written.
try {
FileInputStream fileStream = new FileInputStream(mPlainFile);
// Creates an input stream which decrypts the data as
// it is read from it.
InputStream inputStream;
inputStream = crypto.getCipherInputStream(fileStream, entity);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// org.apache.commons.io.output.ByteArrayOutputStream out = new
// org.apache.commons.io.output.ByteArrayOutputStream(1024);
// Read into a byte array.
// int read;
// byte[] buffer = new byte[1024];
// // You must read the entire stream to completion.
// // The verification is done at the end of the stream.
// // Thus not reading till the end of the stream will cause
// // a security bug.
// int i = 0;
// while ((read = inputStream.read(buffer)) != -1) {
// out.write(buffer, 0, read);
// Log.i(TAG, "bytearrayoutputstream "+i++ + " "+read + " " +
// buffer.length + " "+out.size());
// }
mDecryptedFile = new File(mPlainFile.getPath().substring(0,
mPlainFile.getPath().length() - 4)
+ "_decrypted"
+ (mPlainFile.getPath().substring(mPlainFile.getPath()
.length() - 4, mPlainFile.getPath().length())));
OutputStream outputStream = new FileOutputStream(mDecryptedFile);
// IOUtils.copy(inputStream, outputStream);
try {
final byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1)
outputStream.write(buffer, 0, read);
outputStream.flush();
} catch (Exception e) {
} finally {
outputStream.close();
}
// out.writeTo(outputStream);
// out.flush();
// out.close();
// fileStream.close();
inputStream.close();
// outputStream.flush();
outputStream.close();
return mDecryptedFile.getPath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CryptoInitializationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyChainException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Is there any solution which can work around and encrypts and decrypts large video files too?