0

In my app, we have used CRYPTO provider to create random number.But it was removed in Android N. If app was relying on setSeed() to derive keys from strings, then we should switch to using SecretKeySpec to load raw key bytes directly OR use a real key derivation function (KDF). According to below link

Caused by: java.security.NoSuchProviderException: no such provider: Crypto - Android N

Now my problem is , all existing users using app with old algorithm(SHA1PRNG & CRYPTO provider). All app data has been encrypted using below algorithm and saved in "Shared Preference" and "SQLITE".

If I give an app update with new Encrpt/decrypt algorithm then app might crash when decrypting saved data from SQLITE and shared preference

Can anyone suggest a way to migrate older Encrpt/decrypt algorithm to new one without affecting user.

   public static String encrypt(String seed, String clearText) throws Exception {

    byte[] rawKey = getRawKey(seed.getBytes(STR_ENCODE_UTF8));
    byte[] result = encryptDecrypt(rawKey, clearText.getBytes(STR_ENCODE_UTF8), Cipher.ENCRYPT_MODE);
    return new String(Base64.encode(toHex(result).getBytes(STR_ENCODE_UTF8), Base64.DEFAULT)).trim();
}


public static String decrypt(String seed, String encrypted) throws Exception {

    String decodedStr = new String(Base64.decode(encrypted.trim(), Base64.DEFAULT));
    byte[] rawKey = getRawKey(seed.getBytes(STR_ENCODE_UTF8));
    byte[] enc = toByte(decodedStr);
    byte[] result = encryptDecrypt(rawKey, enc, Cipher.DECRYPT_MODE);
    return new String(result);
}


private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException, NoSuchProviderException {
    KeyGenerator kGen = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
    SecureRandom sr = SecureRandom.getInstance(STR_SHA1PRNG, CRYPTO);
    sr.setSeed(seed);
    kGen.init(128, sr); 
    SecretKey sKey = kGen.generateKey();
    byte[] raw = sKey.getEncoded();
    return raw;
}
Community
  • 1
  • 1
Ananth
  • 115
  • 3
  • 18

1 Answers1

1

Find the original SHA1PRNG implementation. Then copy or re-implement the algorithm, depending on your licensing requirement.

You'd of course create it as a provider containing a KeyFactory if you want to stay compliant to the JCA architecture.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Thanks Maarten....Just an another Question... In order to give backward compatibility for user and for migrating old encrypted data, I need the SHA1PRNG_SecureRandomImpl. Where can I get it? 1. Embedding implementation inside my app will have any copyright issue? 2. Is there any dependency that we can add in our gradle to use implementation 3. Or Any jar file available that I can include in my app for the next release – Ananth May 20 '16 at 14:33
  • https://raw.githubusercontent.com/apache/harmony/java6/classlib/modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java would be the prime suspect. I'll test it to see if I can get the same bytes out of it; it doesn't have too many dependencies. You can do the same of course. – Maarten Bodewes May 20 '16 at 15:54
  • https://github.com/apache/harmony/blob/java6/classlib/modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java is the non-raw one, probably easier – Maarten Bodewes May 20 '16 at 16:00
  • It has a different output it seems than the Sun provider (although also static). Do you have a seed / output combination from Android available? – Maarten Bodewes May 20 '16 at 16:14