Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Issues on Android #23

Closed
srz2 opened this issue Sep 29, 2014 · 23 comments
Closed

Performance Issues on Android #23

srz2 opened this issue Sep 29, 2014 · 23 comments

Comments

@srz2
Copy link

srz2 commented Sep 29, 2014

So I am trying to use this for android and it works but the performance is terrible. It takes several seconds to decrypt an asset I have.

For instance, I have images as low as 50KB to 150KB so nothing too large. But whenever I try to decrypt them, it takes several seconds for them to process. I use this for iOS and it's nearly instantaneous. Would anyone have any suggestions? The function I am using for this process is below...

public byte[] decryptInputStream(InputStream in){
if(in == null)
return null;

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int i = Integer.MAX_VALUE;
    try{
        while((i = in.read(buffer, 0, buffer.length)) > 0)
            outputStream.write(buffer, 0, i);
    }
    catch(Exception e){

    }
    try {
        byte[] decrpytedStream = decryptor.decryptData(outputStream.toByteArray(), KEY.toCharArray());
        return decrpytedStream;
    }
    catch(CryptorException e){
        Log.e("AES Cryptor", "Input Stream Decryption Error");
    }
    return null;
}
@dmjones
Copy link
Contributor

dmjones commented Sep 29, 2014

I'm yet to get to the bottom of these performance issues, to be honest. As discussed in this Stack Overflow answer, it may be simply that Java is much slower than compiled native code. I might try and find a compiled crypto library I can use from Java.

I'm going to investigate this further - there's been too many mentions of slow performance for my liking. I'm also going to write a page describing small changes that can be made to improve performance in some situations.

Note that in your particular case, your performance might be slightly improved by using the streaming API (AES256JNCryptorInputStream). But not significantly, as it seems to be the key generation that's slow.

Can you confirm the decryption is slow when your app is deployed on the phone, rather than being debugged over USB?

@srz2
Copy link
Author

srz2 commented Sep 29, 2014

Yes i can confirm it is slow on the phone. I wouldn't have said anything if it was during debugging as android is generally slow during debugging but these performance issues are observed during deployment. FYI the devices I am using are the Galaxy S3 and the Nexus 7.

@carllindberg
Copy link

If I had to guess, the issue is in the PBKDF2 code. It may be worthwhile to see if a JNI version of that could be made, and a custom Provider wrapped around it. I'm not sure that keypadding providers need to be in a signed .jar in general, and I'm not sure that Android requires those in any event, and Android is probably the primary target for an implementation.

@atomd-zz
Copy link

+1

@dmjones
Copy link
Contributor

dmjones commented Dec 26, 2014

@carllindberg is almost certainly right. I think an NDK crypto library might be the answer. Maybe wrapped around some OpenSSL bits and pieces. Patches extremely welcome.

@SemihAkar
Copy link

+1

@pallavivprasad
Copy link

I tried this library, but as the above comments say, it is very slow, for encryption it takes around 9 seconds and for decryption it takes 3-4 secs. how can it be made faster?

@dmjones
Copy link
Contributor

dmjones commented Mar 26, 2015

@pallavivprasad There isn't really any way to speed it up - this seems to be how long Java takes to perform this operation on Android. I suspect the only solution is to write something native and access it via NDK or similar. I don't have the time to address that currently, but if someone wants to suggest a patch, it would be very welcome.

In general, I think there needs to be a fork for this project for Android. That fork can address this issue, plus other Android-specific problems, like #25.

@skywalkerlw
Copy link

+1, performance improvement is required :)

@cguess
Copy link

cguess commented Dec 14, 2015

I did some tracing and the issue seems to be in the java.security.MessageDigest.digest call that takes place within the PKCS5S2 generation call in the BouncyCastle library. So yes, it seems to be a problem with the Java implementation itself.

Since this library is Java-agnostic it probably wouldn't be a great idea to monkey-patch anything in.

@mr-z-ro
Copy link

mr-z-ro commented Jul 25, 2016

Just wanted to give an update in case anyone else comes across this - RNCryptor officially has mentioned in a couple of places that this is a performance issue with the java library being used on Android, and has called for a JNI solution.

In doing some digging over the weekend, I came across this library which has accomplished that. The benchmarking in the README there seems to confirm that the JNI method reduces much of the latency in both encryption and decryption. Worth checking out, and perhaps working into the official RNCryptor arsenal...

@rnapier
Copy link
Member

rnapier commented Jul 25, 2016

@msgrasser Thanks for the reminder again; I keep meaning to bring that one "into the fold." I haven't done an extensive review of it, but it looks very solid.

@mr-z-ro
Copy link

mr-z-ro commented Jul 25, 2016

@rnapier Great!

I only mentioned it here because I started implementing a JNI for RNCryptor myself and had [stupidly] put in a couple of hours before a lightbulb went off saying "Well since Rob suggested this formally in the JNCryptor README, there must be someone else working on it." Just wanted to link to it somewhere within this project so people could come across it before [stupidly] spending time on starting from scratch like I did.

Anyway, thank you so very much for the awesome set of libs - they are a much appreciated gift to the world of secure data storage/transmission!!!

@hoanghiephui
Copy link

Do not know if you can build a version native for android?

@rnapier
Copy link
Member

rnapier commented Oct 21, 2016

@hoanghiephui, please see https://github.com/TGIO/RNCryptorNative, referenced earlier in this thread.

@hoanghiephui
Copy link

@rnapier Oh! Thanks a lot, I tried, but apparently it does not work well. I am using your library for the ios, the data sent to the android, it has not been decoded.

@rnapier
Copy link
Member

rnapier commented Oct 21, 2016

@hoanghiephui I don't understand the question. RNCryptorNative should be completely compatible with the other RNCryptor implementations.

@hoanghiephui
Copy link

I'm having a problem, when data is encrypted by android lib rncryptornative. It fails to decrypt on ios (using same passcode)

And seems like test vectors wasn't processed, I think there're things that aren't running properly with your algorithm. I hope you could spend some time to help it works better

@rnapier
Copy link
Member

rnapier commented Oct 22, 2016

If you believe a test vector is failing in TGIO/RNCryptorNative, you should definitely open an issue there with the vector that's failing. The vast majority of the time when a message fails to decrypt its because you did not send precisely the same message (byte for byte) to the decryptor that you got from the encryptor. It is almost always an encoding problem, not a crypto problem. That said, it is possible that RNCryptorNative has some bug, but you would need to open an issue there with a failing case (the JNCryptor issue board can't really help you).

@hoanghiephui
Copy link

Ok, Thanks a lot!

@babulpatel1309
Copy link

For too slow decryption and encryption here is the perfect solution.

https://github.com/TGIO/RNCryptorNative?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=3643)

found this library while i was searching for alternatives of JNCryptor. This lib derived from native and it does pretty well job.
I had tried many solution but none of that was working and finally this library did.

You can check the compare graph below.

1

25

@dmjones
Copy link
Contributor

dmjones commented Sep 1, 2017

@babulpatel1309 Thanks for the pointer. However, please don't spam this message over any more issues, thanks. This is the right place to put it.

@dmjones dmjones closed this as completed Sep 1, 2017
@vijayendra-tripathi
Copy link

I haven't tested this personally but from what I know after introduction of ART in Android Nougat, the system turns byte code into native and thus performance of this library must have improved a lot. Android Nougat was launched sometime in August 2016 and most of the comments here are before or just around this time. The benchmark used by @babulpatel1309 in 2017 looks interesting but I am not sure what OS version and device was used for comparison. I will try on the newer versions and see how it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests