0

I have done Encryption and Decryption in android when file downloading but I want to improve time performance when file decrypted. My problem is when I am downloading any file so I have add encryption over there but at this stage I am showing Progress loader so it looks good but but when file completely download and try to open that file then it is decrypted that file this time it's taking too much time . which is look very bad. How can I reduce decryption time? Here is my code

Encryption Code

byte data[] = new byte[1024];

String seed = "password";

byte[] rawKey = getRawKey(seed.getBytes());
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

output = new CipherOutputStream(output, cipher);

long total = 0;

while ((count = input.read(data)) != -1) {
    total += count;
    publishProgress("" + (int) ((total * 100) / lenghtOfFile));

    output.write(data, 0, count);
}

Decryption Code Here:

String newPath = sdCardPath + "/" + dPdfName;
File f1 = new File(newPath);
if (!f1.exists())
    try {
        f1.createNewFile();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

try {
    InputStream fis = new FileInputStream(f);
    OutputStream fos = new FileOutputStream(f1);
    String seed = "password";
    byte[] rawKey = getRawKey(seed.getBytes());
    SecretKeySpec skeySpec = new SecretKeySpec(rawKey,
            "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);

    fis = new CipherInputStream(fis, cipher);
    int b;
    byte[] data = new byte[4096];
    while ((b = fis.read(data)) != -1) {
        // fos.write(cipher.doFinal(data), 0, b);
        fos.write(data, 0, b);
    }
    fos.flush();
    fos.close();
    fis.close();

} catch (Exception e) {
    // TODO: handle exceptionpri
    e.printStackTrace();
}

Get Row Key Method:

private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    sr.setSeed(seed); 
    kgen.init(128, sr); 
    SecretKey skey = kgen.generateKey(); 

    byte[] raw = skey.getEncoded();
    return raw;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Alok Tiwari
  • 607
  • 2
  • 7
  • 21
  • I guess it takes the time it takes ... – Henry Jul 04 '14 at 08:08
  • [Android](http://stackoverflow.com/questions/7282930/android-slow-aes-decryption) [crypto](http://stackoverflow.com/questions/4663912/slow-aes-decryption-in-android) [is slow](http://stackoverflow.com/questions/6257945/aes-decryption-on-android-too-slow-to-be-usable-will-ndk-be-faster-other-ideas?rq=1), [very](http://stackoverflow.com/questions/7713166/speed-up-encryption-decryption) [slow](http://stackoverflow.com/questions/10619770/android-aes-encryption-decryption). – Oleg Estekhin Jul 04 '14 at 08:41
  • What i need to implement for better performance – Alok Tiwari Jul 04 '14 at 08:54

2 Answers2

0

Suggestions:

1) move the decryption to another asynctask and add another progress indicator.

2) reserve last, say, 10% of the progress indicator to decryption. This is what I actually did once, but I was doing an integrity check (against an MD5 hash IIRC), not decryption.

3) move the decryption to the downloading asynctask, decrypt each received portion of data immediately and so hide the decryption time behind the download time.

4) not sure this will be any faster, but you may have two service threads: one downloading file and another decrypting it. It's better no to use AsyncTask here, because they may behave differently on different versions of Android (including sequential execution on a single thread, see Is AsyncTask really conceptually flawed or am I just missing something? for the discussion, and my note https://stackoverflow.com/a/14602486/755804 )

Note also that the thread responsible for downloading and decryption belongs to Model (in MVC sense) and must not be owned by an Activity which is a Controller that cannot outlive a screen turn: https://stackoverflow.com/a/14603375/755804

If your download takes a long time, you may be interested in resuming interrupted downloads, and it's better to think about it from the very beginning. It's always easier to modify simple solutions, and multi-threaded solutions are rather complex. If you transfer a number of files, it may happen that one of them gets broken during transfer, and you may want an option to retransfer only the file(s) that are broken. You may also want an integrity check.

Community
  • 1
  • 1
18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
0

Make sure you align the data buffer to the block size of the encryption.

For a Example see: https://stackoverflow.com/a/33171612/475496

Using this method has speedup our encryption enormous.

Community
  • 1
  • 1
StaticBR
  • 1,019
  • 1
  • 11
  • 25