0

I have an encrypted messenger app that Android P broke. In P any call to any call to

SecureRandom.getInstance("SHA1PRNG", "Crypto") 

will throw NoSuchProviderException.

EDIT If we are not supposed to use SHA1PRNG, then what provider are we supposed to use ??

In my app the following method gets such an exception . . .

public static AESSeedAndMessage doAESEncrypt(String inString)
    {
        //returnes encrypted message along with UNencrypted seed
        AESSeedAndMessage returnStuff = new AESSeedAndMessage();
        returnStuff.seed = generateAESSeed();  //get a random seed
        byte[] encodedBytes = null;
        // Set up secret key spec for 128-bit AES encryption and decryption
        SecretKeySpec sks = null;
        try 
        {
        SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG", new CryptoProvider() );

            sr.setSeed(returnStuff.seed.getBytes());
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128, sr);
            sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");

            // Encode the original data with AES
            Cipher c = Cipher.getInstance("AES");
            c.init(Cipher.ENCRYPT_MODE, sks);
            encodedBytes = c.doFinal(inString.getBytes());
        } 
        catch (Exception e) 
        {
            returnStuff.text = "error";
            return returnStuff;
        }
        returnStuff.text = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
        return returnStuff;
}

I find quite a bit of material on this issue but I haven't been able to find out what to do to replace the removal of that crypto provider. What do I need to do in order to make this method work, hopefully, in all versions of Android?

EDIT FYI I had a problem with this code back in Android N when crypto was eliminated and had to add the following class to make it work in N.

import java.security.Provider;
/**
 * Created by gary on 12/30/2017.
 */
//this is because Android N eliminated crypto
public class CryptoProvider extends Provider {
    /**
     * Creates a Provider and puts parameters
     */
    public CryptoProvider() {
        super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
        put("SecureRandom.SHA1PRNG",
                "org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
        put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
    }
}
Dean Blakely
  • 3,535
  • 11
  • 51
  • 83
  • 1
    Hopefully, it is deprecated, and you can see the example from [here](https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html). You can select the instance form the [list](https://developer.android.com/reference/javax/crypto/KeyGenerator). – kelalaka Apr 16 '19 at 17:25
  • 2
    If you really need the `SHA1PRNG` you have no choice: include the PRNG implementation into your app. Anyway misusing SHA1PRNG as a key generator is a very bad idea. You should have migrated that code to a `PBEKeySpec` based key generation long time ago. – Robert Apr 16 '19 at 18:22
  • kelalaka, it was depreciated in N and is gone in P – Dean Blakely Apr 16 '19 at 23:26
  • Robert, what I "need" is a code example of getting a random AES key. Can you point me to a PBEKeySpec implementation? – Dean Blakely Apr 16 '19 at 23:30
  • `byte [] aesKey = new byte[16]; SecureRandom sr = new SecureRandom(); sr.nextBytes(aesKey); ` – President James K. Polk Apr 17 '19 at 11:09
  • @Dean: But you are not using a random key, you are using a key that is derived from the content of `inString` (and you are misusing SecureRandom for that). An example how to derive a key from a password using `PBEKeySpec` you can find e.g. here:https://stackoverflow.com/a/992413/150978 – Robert Apr 17 '19 at 11:57
  • For backwards compatibility - i.e. to **move away** from it - you could copy the algorithm into your application from an old Android source tree. That way you always have access to the correct algorithm. Note that it changed a few times and **was broken** in the initial versions of Android (I think copied from Apache Harmony or similar - including their mistakes). So in addition to Robert's remark, make sure you get the right version of the source code. – Maarten Bodewes Apr 19 '19 at 18:39
  • Oh yuk, that's a terrible hack to get the functionality back, but I applaud you for it. You can of course put the implementation class anywhere, there is no need to keep it in the Apache Harmony package space. – Maarten Bodewes Apr 19 '19 at 18:44

0 Answers0