Securerandom Provider "crypto" Unavailable In Android N For Deterministially Generating A Key
Solution 1:
I had a discussion with the Android Security team about this recently.
In Android N, SHA1PRNG was removed because we don't have a secure implementation of it. Specifically, calling .setSeed(long)
before requesting output from the PRNG replaces all of the entropy in the SecureRandom instance.
This behavior has long been pointed to as a security failure (read: frequently causes subtle bugs in apps), so we chose not to replicate it when the SecureRandom provider was replaced.
If you need a PRNG, then just use new SecureRandom()
.
That said... SecureRandom() is not designed to be used as a key derivation function, as you've done in your example. Please don't do this! Instead, use an algorithm such as PBKDF2, available via SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
.
We've been warning developers about this for a while. Please see these posts:
- Android Developers Blog: Using Cryptography to Store Credentials Safely
- Android 4.2 broke my encrypt/decrypt code and the provided solutions don't work
IF YOU REALLY NEED SHA1PRNG, EVEN AFTER ALL OF THAT... then the workaround is to copy the implementation out of the Android source, like @artjom-b mentioned in his answer.
But please, only do this if you need compatibility while migrating to PBKDF2 or similar.
Solution 2:
Using a PRNG such as SecureRandom for deriving data deterministically is generally a bad idea, because there is a history of breaking changes. It is always a good idea to use a specific implementation and include that with your app. It is possible to just copy the implementation code in your case.
SecureRandom.getInstance("SHA1PRNG", "Crypto");
looks up the "Crypto" provider which is org.apache.harmony.security.provider.crypto.CryptoProvider
in Android 5.1.1. It redirects to org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
as the actual implementation. You can easily copy the code into your project under a different package and be sure to comply with the code license.
Then you can use it like this:
sr = new SecureRandom(new your.pkg.SHA1PRNG_SecureRandomImpl(), null);
The second provider argument is not used according to the code, but you can create a dummy provider.
The proper way to generate a key from some seed is to use a key derivation function (KDF). If seed
is password-like, then PBKDF2 is a good KDF when a lot of iterations are specified. If seed
is key-like, then a KBKDF like HKDF is recommended.
Solution 3:
I added one class for CryptoProvider you can replace SecureRandom.getInstance("SHA1PRNG", "Crypto"); to SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
you can refer following link for solution, it working for me;
Post a Comment for "Securerandom Provider "crypto" Unavailable In Android N For Deterministially Generating A Key"