美文网首页Android专题
Android 9.0 加密适配

Android 9.0 加密适配

作者: 木木Jump | 来源:发表于2019-01-23 15:56 被阅读34次

    Android 9.0 加密报错:

    NoSuchAlgorithmException: class configured for SecureRandom (provider: Crypto) cannot be found

    调用方法:

    private static byte[] getRawKey(byte[] seed) throws Exception {
            KeyGenerator kgen = KeyGenerator.getInstance(AES);
            //for android
            SecureRandom sr = null;
            // 在4.2以上版本中,SecureRandom获取方式发生了改变
            if (android.os.Build.VERSION.SDK_INT >= 17) {
                sr = SecureRandom.getInstance(SHA1PRNG, "Crypto");
            } else {
                sr = SecureRandom.getInstance(SHA1PRNG);
            }
            // for Java
            // secureRandom = SecureRandom.getInstance(SHA1PRNG);
            sr.setSeed(seed);
            kgen.init(128, sr); //256 bits or 128 bits,192bits
            //AES中128位密钥版本有10个加密循环,192比特密钥版本有12个加密循环,256比特密钥版本则有14个加密循环。
            SecretKey skey = kgen.generateKey();
            byte[] raw = skey.getEncoded();
            return raw;
        }
    

    问题原因:

    The Crypto provider has been deleted in Android P (and was deprecated in Android N), so the code will crash.
    报错代码:SecureRandom.getInstance(SHA1PRNG, "Crypto")
    这个是因为Crypto provider 在Android9.0中已经被Google删除了,调用的话就会发生crash。

    解决办法:

    使用Google提供的适配方法:InsecureSHA1PRNGKeyDerivator

    github下载地址

    使用如下方法生成SecretKeySpec 对象

    private static SecretKeySpec deriveKeyInsecurely(String password) {
            byte[] passwordBytes = password.getBytes(StandardCharsets.US_ASCII);
            return new SecretKeySpec(InsecureSHA1PRNGKeyDerivator.deriveInsecureKey(passwordBytes, AESUtils.KEY_SIZE), "AES");
        }
    

    具体Utils可以参考这个AESUtils类

    参考文章:AndroidP AES 加密适配


    Android 9.0系统加密变更:

    (1)加密变更1

    从 Android P 开始,对于 AndroidOpenSSL (也称为 Conscrypt) 提供程序所重复的、来自于 BC 提供程序的部分功能,我们计划将予以弃用。此举的目的不是因为对 BC 提供程序的实施安全存在疑虑,而是因为重复功能会造成额外的成本和风险,却无法带来太多益处。 如果您按名称或实例指定提供程序 - 例如,Cipher.getInstance("AES/CBC/PKCS7PADDING", "BC") 或Cipher.getInstance("AES/CBC/PKCS7PADDING", Security.getProvider("BC")) - 则 Android P 的行为将取决于您应用的目标 API 级别。对于目标级别为 Android P 或之后版本的应用,调用会抛出 NoSuchAlgorithmException。

    (2)加密变更2

    Nougat 开始弃用 Crypto 提供程序。以 API 24 (Nougat) 或之后级别为目标的应用程序请求则会失败.
    在 Android P 中,我们计划完全移除 Crypto 提供程序。在移除后,所有对 SecureRandom.getInstance("SHA1PRNG", "Crypto") 的调用都会抛出 NoSuchProviderException。

    (3)加密变更3

    P中在Conscrypt中对算法加入了额外的实现,适合参数有AES,DESEDE,OPEP,和EC(仅支持命名的曲线)。此外Android P中已弃用以上参数以及许多算法的BouncyCastle版本。

    (4)其他加密变更
    • 在使用 PBE 密钥的情况下,若您的应用未能提供 Bouncy Castle 要求的初始化向量,那么您将收到警告信息;
    • ARC4的 Conscrypt 实现允许您指定 ARC4/ECB/NoPadding 或者 ARC4/NONE/NoPadding;
      *Android P 移除了 Crypto Java Cryptography Architecture (以下简称 JCA) 加密服务提供商。因此,若您的应用调用 SecureRandom.getInstance("SHA1PRNG", "Crypto"),将会引发 NoSuchProviderException 异常;
    • 应用从大于密钥结构的缓冲区中解析 RSA 密钥时,不再会引发异常

    相关文章

      网友评论

        本文标题:Android 9.0 加密适配

        本文链接:https://www.haomeiwen.com/subject/dqlrjqtx.html