-1

I'm encrypting and decrypting files in my App, but if the file is too large it takes minutes, is it possible to improve speed? this is encryption/decryption code

    private static void startCrypting(int cipherMode, String key, File inputFile,
                             File outputFile) throws MediaCodec.CryptoException {
    try {
        Key secretKey = new SecretKeySpec(key.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(cipherMode, secretKey);

        FileInputStream inputStream = new FileInputStream(inputFile);
        FileOutputStream outputStream = new FileOutputStream(outputFile);

        CipherOutputStream out = new CipherOutputStream(outputStream, cipher);
        byte[] buffer = new byte[8192];
        int count;
        while ((count = inputStream.read(buffer)) > 0) {
            out.write(buffer, 0, count);
        }

        out.flush();
        out.close();
        outputStream.close();
        inputStream.close();

    } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | IOException ex) {
        ex.printStackTrace();
    }
}
Jemo Mgebrishvili
  • 5,187
  • 7
  • 38
  • 63
  • I don't think you can do much better. The file must be really large if this takes minutes. – Henry Feb 28 '17 at 06:33
  • If security is not much of a concern here then you can go with DES algorithm symmetric key. It is weak as compared to AES, but will improve the performance. – vijayinani Feb 28 '17 at 06:34
  • 2
    General advice: **Always use a fully qualified Cipher string.** `Cipher.getInstance("AES");` may result in different ciphers depending on the default security provider. It most likely results in `"AES/ECB/PKCS5Padding"`, but it doesn't have to be. If it changes, you'll lose compatibility between different JVMs. For reference: [Java default Crypto/AES behavior](http://stackoverflow.com/q/6258047/1816580) – Artjom B. Feb 28 '17 at 06:50
  • 2
    **Never use [ECB mode](http://crypto.stackexchange.com/q/14487/13022)**. It's deterministic and therefore not semantically secure. You should at the very least use a randomized mode like [CBC](http://crypto.stackexchange.com/q/22260/13022) or [CTR](http://crypto.stackexchange.com/a/2378/13022). It is better to authenticate your ciphertexts so that attacks like a [padding oracle attack](http://crypto.stackexchange.com/q/18185/13022) are not possible. This can be done with authenticated modes like GCM or EAX, or with an [encrypt-then-MAC](http://crypto.stackexchange.com/q/202/13022) scheme. – Artjom B. Feb 28 '17 at 06:51
  • Depending on the type of data you encrypt, adding compression to the stream prior to encryption can speed up the process, by reducing the amount of data that needs to be encrypted. – Ebbe M. Pedersen Feb 28 '17 at 15:12

1 Answers1

1

Simple. Add a BufferedInputStream between the FileInputStream and the CipherInputStream whewn decrypting, or a BufferedOutputStream between the CipherOutputStream and the FileOutputStream when encrypting, as appropriate. This will regularize the I/O to/from the file to 8192 bytes at a time, instead of whatever the cipher streams may do.

The buffer size of the buffered streams doesn't even matter much: it is 8192 by default and there is no harm in increasing that.

You could also increase the size of your own buffer.

user207421
  • 305,947
  • 44
  • 307
  • 483