2

I develop an android application for encrypt files on the phone. By searching, i found this topic : How to encrypt file from SD card using AES in Android?

The method works fine but it is very slow to encrypt files... At this line : byte[] d = new byte[8]; why only 8 bytes ? can't we set an higher value ?

Also, do you know a way to encrypt files fastly ? I heard of crypto++ for native code implementation but how can I implement JNI on my application ?

Thank you,

EDIT : Encryption function

public void encrypt (String RSAPrivateKey, String Key, byte[] iv, String zipname, ZipEncryptAsyncTask task) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
    {
        FileInputStream     fis     = new FileInputStream   (zipname + ".temp");
        FileOutputStream    fos     = new FileOutputStream  (zipname);
        SecretKeySpec       sks     = new SecretKeySpec     (Base64.decode(Key, Base64.DEFAULT), "AES");
        IvParameterSpec     ivspec  = new IvParameterSpec   (iv);
        Cipher              cipher  = Cipher.getInstance    ("AES/CBC/PKCS5Padding");

        fos.write(String.valueOf(RSAPrivateKey.getBytes().length).getBytes());
        fos.write(RSAPrivateKey.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, sks, ivspec);
        CipherOutputStream cos = new CipherOutputStream(fos, cipher);

        long size = 0;
        byte[] d = new byte[8];
        for(int b; (b = fis.read(d)) != -1; )
        {
            cos.write(d, 0, b);
            task.doProgress((size += 8));
        }

        cos.flush();
        cos.close();
        fis.close();

        new File(zipname + ".temp").delete();
    }
Community
  • 1
  • 1
Flo354
  • 159
  • 2
  • 14
  • Please, could you post your encryption code? Maybe we can find something to scratch there – Jorge_B Dec 24 '13 at 10:08
  • I suggest you to wrap your `FileInputStreams` and `FileOutputStreams` into `BufferedInputStreams` and `BufferedOutputStreams`, profile both versions and compare performance. You should even try with different buffer sizes. By the way, you should investigate if you can refactor out of the method that `cipher` variable and its initialization `cipher.init`, looks like it could improve something? – Jorge_B Dec 24 '13 at 14:05
  • You certainly should use larger values than 8. Perhaps 2*1024 or something of similar size. – CodesInChaos Dec 24 '13 at 14:27
  • btw. `size += 8` should be `size += b` – CodesInChaos Dec 24 '13 at 14:28
  • Okay, so the BufferedStreams doesn't change anything. But the array size change everything. Indeed, i set the buffer to 2048 instead of 8, and the speed is good now ! However, how can I know the maximum size of the buffer ? Thank you, – Flo354 Dec 24 '13 at 14:42
  • It may be\ that if you use `java.nio` `ByteBuffer` from a mapped file, and calculate the size of the encrypted file and create it in one go that you could speed up this *quite* a bit more. – Maarten Bodewes Dec 27 '13 at 02:31
  • @Flo354 Did that work out? I'm posting under my real name instead of owlstead now. If that's the case, could you create an answer? This question is left open right now. – Maarten Bodewes Oct 02 '15 at 10:26
  • I simply used a larger buffer. I did not used a mapped file. I will create an answer – Flo354 Oct 25 '15 at 13:05

2 Answers2

1

As an alternative, you could consider changing the cypher mode you are using. CBC mode must be used serially, block by block. Counter mode (CTR) can be run in parallel with different blocks being encrypted simultaneously. Of course there are overheads to parallel processing, and you will need to rework your code, but if buffer resizing does not give you enough speed gains, then it might be the next option to try.

rossum
  • 15,344
  • 1
  • 24
  • 38
0

as @CodesInChaos said, a way to do this, is to increase the size of the buffer. Now I do a benchmark which determines the best size for the buffer and I use the optimal value.

Flo354
  • 159
  • 2
  • 14