由于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);
}
}
}