开发工具:Android Studio

 

项目中若使用 SecureRandom.getInstance("SHA1PRNG", "Crypto") ,会给出以下警告:

The Crypto provider has been deleted in Android P (and was deprecated in Android N), so the code will crash. less... (Ctrl+F1) 
The Crypto provider has been completely removed in Android P (and was deprecated in an earlier release). This means that the code will throw a NoSuchProviderException and the app will crash. Even if the code catches that exception at a higher level, this is not secure and should not be used. 

即:Crypto provider 在 Android N(7.0)中已弃用,在Android P(9.0) 中已删除。

附相关上下文参考代码:

byte[] lSeedBytes = "password".getBytes();
SecureRandom lSecureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
KeyGenerator lKeyGenerator = KeyGenerator.getInstance("AES");
lSecureRandom.setSeed(lSeedBytes);
lKeyGenerator.init(256, lSecureRandom);
SecretKey lSecretKey = lKeyGenerator.generateKey();
byte[] lResultEncoded = lSecretKey.getEncoded();

两种情况:

1, targetSdkVersion < 24 时,在Android P 以上的设备会出现: java.security.NoSuchProviderException: no such provider: Crypto 

2,targetSdkVersion >= 24 时,在Android N 以上的设备会出现: java.security.NoSuchProviderException: no such provider: Crypto

此问题官方已经给出了参考方案: https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html

但只给出了部分示例代码,对于存储,并未提供相关代码,如需要,可参考以下:

private static byte[] mSaltCache;
private static byte[] getSecretKeyEncoded(String password) throws Exception {
    int iterationCount = 1000;
    int saltLength = 32; // bytes; should be the same size as the output (256 / 8 = 32)
    int keyLength = 256; // 256-bits for AES-256, 128-bits for AES-128, etc
    if (mSaltCache == null || mSaltCache.length != saltLength) {
        SharedPreferences lSP = Application.getInstance().getSharedPreferences("crypto_info", Context.MODE_PRIVATE);
        String lSaveStr = lSP.getString("salt", "");
        if (!TextUtils.isEmpty(lSaveStr)) {
            mSaltCache = toArr(lSaveStr);
        }
        if (mSaltCache == null || mSaltCache.length != saltLength) {
            byte[] salt = new byte[saltLength]; // Should be of saltLength
            SecureRandom random = new SecureRandom();
            random.nextBytes(salt);
            lSP.edit().putString("salt", toStr(salt)).commit();
            mSaltCache = salt;
        }
    }
    KeySpec keySpec = new PBEKeySpec(password.toCharArray(), mSaltCache, iterationCount, keyLength);
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
    SecretKey key = new SecretKeySpec(keyBytes, "AES");
    return key.getEncoded();
}

工具方法:

public static String toStr(byte[] aBytes) {
    return toStr(aBytes, null);
}

public static String toStr(byte[] aBytes, String aSplit) {
    if (aBytes == null) return null;
    int lLength = aBytes.length;
    if (lLength <= 0) return "";
    if (TextUtils.isEmpty(aSplit)) aSplit = ",";
    StringBuilder lSB = new StringBuilder();
    for (int i = 0; i < lLength; i++) {
        lSB.append(String.valueOf(aBytes[i]));
        if (i != lLength - 1) lSB.append(aSplit);
    }
    return lSB.toString();
}

public static byte[] toArr(String aStr) {
    return toArr(aStr, null, (byte) 0);
}

public static byte[] toArr(String aStr, String aSplit, byte aDefaultValue) {
    if (TextUtils.isEmpty(aStr)) return null;
    if (TextUtils.isEmpty(aSplit)) aSplit = ",";
    String[] lItems = aStr.split(aSplit);
    int lLength = lItems.length;
    byte[] lResult = new byte[lLength];
    for (int i = 0; i < lLength; i++) {
        try {
            lResult[i] = Byte.parseByte(lItems[i]);
        } catch (Exception e) {
            lResult[i] = aDefaultValue;
        }
    }
    return lResult;
}

以上代码在官方示例基础上进行简单修改,仅供参考。

 

其他方案:

网上流传最多的一种方式为:

将: 

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

修改为:

SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
public class CryptoProvider extends Provider {
    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");
    }
}

 

但此方式仅在 24 <= targetSdkVersion < 28 时,在 Android N 到 Android P 之间生效。

 

 

原文地址: https://blog.csdn.net/u011859715/article/details/83784238

尊重原创,转载请声明出处,谢谢!

 

 

 

更多相关文章

  1. Android中的动画
  2. 高通平台Android(安卓)N SystemUI添加qcnvitems qcrilhook
  3. Android(安卓)ViewFlipper简单示例
  4. 使用Android(安卓)studio导入源码工程
  5. android如何改变默认横竖屏方向
  6. android底部中间凸出导航 BottomProtruding
  7. android-使App全屏 - 随心
  8. AndroidStudio用gradle编译中文乱码
  9. android 底部菜单写法之FragmentTabHost

随机推荐

  1. Android(安卓)获取url中的参数
  2. android View 绘制完成监听
  3. Android下多页显示技巧
  4. 改变tab中indicator文本的颜色
  5. Android(安卓)阻断adb install
  6. Android一键锁屏开发全过程【源码】【附
  7. Android(安卓)结束进程的方法
  8. android 初级入门
  9. android backgroud alpha
  10. 2010.12.26——— android 获得手机号码