Android P AES加密的问题

由于Crypot provider被禁用在android P设备上使用会抛出java.security.NoSuchProviderException: no such provider: Crypto异常

网上没有找到好的解决方法

参考谷歌官方代码先这样解决吧,有同样问题的可以参考一下

google代码

https://android.googlesource.com/platform/development/+/master/samples/BrokenKeyDerivation/src/com/example/android/brokenkeyderivation/BrokenKeyDerivationActivity.java

public class AESUtilsHelper
{

    //加密key
    private static  final  String key="unguessable";
    /**
     * 对文件进行AES加密
     * @param oldFile
     * @param newFile
     * @return
     */
    public static boolean encryptFile(File oldFile, File newFile,Context context){
        //新建临时加密文件
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(oldFile);
            outputStream = new FileOutputStream(newFile);
            Cipher cipher = initAESCipher( Cipher.ENCRYPT_MODE,context);
            //以加密流写入文件
            CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
            byte[] cache = new byte[1024];
            int nRead = 0;
            while ((nRead = cipherInputStream.read(cache)) != -1) {
                outputStream.write(cache, 0, nRead);
                outputStream.flush();
            }
            cipherInputStream.close();
        }  catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        }  catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {

            try {
                if (outputStream!=null){
                    outputStream.close();
                }
                if (inputStream!=null){
                    inputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();

            }
        }
        return true;
    }


    /**
     * AES方式解密文件
     * @param sourceFile 待解密的文件
     * @return 解密完成文件
     */
    public static File decryptFile(File sourceFile,File outFile,Context context){

        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {


            Cipher cipher = initAESCipher(Cipher.DECRYPT_MODE,context);
            inputStream = new FileInputStream(sourceFile);
            outputStream = new FileOutputStream(outFile);
            CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
            byte [] buffer = new byte [1024];
            int r;
            while ((r = inputStream.read(buffer)) >= 0) {
                cipherOutputStream.write(buffer, 0, r);
            }
            cipherOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("decryptFile","-----"+e.getMessage());
            return null;
        }finally {
            try {
                if (outputStream!=null){
                    outputStream.close();
                }
                if (inputStream!=null){
                    inputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
                Log.e("decryptFile","-----"+e.getMessage());

            }

        }
        return outFile;
    }

    /**
     * 初始化 AES Cipher
     * @param cipherMode
     * @return
     */
    private static Cipher initAESCipher( int cipherMode ,Context context) {

        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("AES");
            cipher.init(cipherMode, deriveKeySecurely(context,key,KEY_SIZE));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return cipher;
    }


    /** iv大小(位) **/
    private static final int IV_SIZE = 16;
    /** 密钥大小(位) **/
    private static final int KEY_SIZE = 32;
   
    private static final String IV_FILE_NAME = "AES_IV";
   
    private static final String SALT_FILE_NAME = "AES_SALT";
   
    /**
     * 生成一个安全的密钥
     * @param password 生成密钥的seed
     * @param keySizeInBytes 密钥大小(位)
     * @return 密钥
     */
    private static SecretKey deriveKeySecurely(Context context, String password, int keySizeInBytes) {
        // Use this to derive the key from the password:
        KeySpec keySpec = new PBEKeySpec(password.toCharArray(), retrieveSalt(context),
                100 /* iterationCount */, keySizeInBytes * 8 /* key size in bits */);
        try {
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
            byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
            return new SecretKeySpec(keyBytes, "AES");
        } catch (Exception e) {
            throw new RuntimeException("Deal with exceptions properly!", e);
        }
    }

    private static byte[] retrieveSalt(Context context) {
        // Salt must be at least the same size as the key.
        byte[] salt = new byte[KEY_SIZE];
        // Create a random salt if encrypting for the first time, and save it for future use.
        readFromFileOrCreateRandom(context, SALT_FILE_NAME, salt);
        return salt;
    }

    private static void readFromFileOrCreateRandom(Context context, String fileName, byte[] bytes) {
        if (fileExists(context, fileName)) {
            readBytesFromFile(context, fileName, bytes);
            return;
        }
        SecureRandom sr = new SecureRandom();
        sr.nextBytes(bytes);
        writeToFile(context, fileName, bytes);
    }

    private static boolean fileExists(Context context, String fileName) {
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);
        return file.exists();
    }

    @SuppressWarnings("unused")
    private static void removeFile(Context context, String fileName) {
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);
        //noinspection ResultOfMethodCallIgnored
        file.delete();
    }

    private static void writeToFile(Context context, String fileName, byte[] bytes) {
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);

        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Couldn't write to " + fileName, e);
        }
    }

    private static void readBytesFromFile(Context context, String fileName, byte[] bytes) {
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);

        try {
            FileInputStream fis = new FileInputStream(file);
            int numBytes = 0;
            while (numBytes < bytes.length) {
                int n = fis.read(bytes, numBytes, bytes.length - numBytes);
                if (n <= 0) {
                    throw new RuntimeException("Couldn't read from " + fileName);
                }
                numBytes += n;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Couldn't read from " + fileName, e);
        }
    }



}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值