I have been following the tutorial "How do I encrypt and decrypt files using DES?" to add a simple file encryption to an existing Android 4+ app.
Everything works fine, except that the encryption and decryption is very, very slow.
The following two methods are pretty much the complete tutorial:
public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey desKey = skf.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE
if (mode == Cipher.ENCRYPT_MODE) {
cipher.init(Cipher.ENCRYPT_MODE, desKey);
CipherInputStream cis = new CipherInputStream(is, cipher);
doCopy(cis, os);
} else if (mode == Cipher.DECRYPT_MODE) {
cipher.init(Cipher.DECRYPT_MODE, desKey);
CipherOutputStream cos = new CipherOutputStream(os, cipher);
doCopy(is, cos);
}
}
public static void doCopy(InputStream is, OutputStream os) throws IOException {
byte[] bytes = new byte[64];
int numBytes;
// Why is this taking so long?
while ((numBytes = is.read(bytes)) != -1) {
os.write(bytes, 0, numBytes);
}
os.flush();
os.close();
is.close();
}
Quite simple and basic, but it takes about 20-30 seconds to de/encrypt a 1 MB file. In detail it is the while-loop that copies the bytes between the two streams which is so slow.
Changing the size of the byte[] to a bigger value like 65536 to read more bytes at once does not change anything. I thought reading more bytes at once would speed up the process but this is not the case.
Copying data between "normal" streams without encryption does not take so long. Is it really the encryption that is this expensive? I have been using similar encryptions on other plattforms and such delays have never been a problem.
The tutorial uses DES but changing the algorithm to something different, e.g. AES does not change anything either.
Any ideas how I can speed this up?