Android N中不再支持“Crypto”的解决方案
来源:互联网 发布:图片处理器软件 编辑:程序博客网 时间:2024/06/07 07:14
这个问题的相关说明你可以看看这篇博文。
按照官方说明,我写了一个工具类,下面是代码:
/** * AES 加密工具类,适配Android7.0,相对老的加密工具,提升了安全性 */public class AESUtil { /** iv大小(位) **/ private static final int IV_SIZE = 16; /** 密钥大小(位) **/ private static final int KEY_SIZE = 32; /** iv文件名 **/ private static final String IV_FILE_NAME = "AES_IV"; /** salt文件名 **/ private static final String SALT_FILE_NAME = "AES_SALT"; // iv文件和salt文件位于外置储存卡的Android/data/com.example.name(你的App的包名)/files/Download目录下,文件名如上面所示 /** * 生成一个安全的密钥 * @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[] retrieveIv(Context context) { byte[] iv = new byte[IV_SIZE]; // Ideally your data should have been encrypted with a random iv. This creates a random iv // if not present, in order to encrypt our mock data. readFromFileOrCreateRandom(context, IV_FILE_NAME, iv); return iv; } 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); } } private static byte[] encryptOrDecrypt( byte[] data, SecretKey key, byte[] iv, boolean isEncrypt) { try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7PADDING"); cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); return cipher.doFinal(data); } catch (GeneralSecurityException e) { throw new RuntimeException("This is unconceivable!", e); } } private static byte[] encryptData(byte[] data, byte[] iv, SecretKey key) { return encryptOrDecrypt(data, key, iv, true); } private static byte[] decryptData(byte[] data, byte[] iv, SecretKey key) { return encryptOrDecrypt(data, key, iv, false); } // 本工具类唯一提供的两个公共方法,用来加密和加密数据 /** * 加密数据 * @param data 待加密的数据 * @param password 密钥 * @return 已加密的数据 */ public static byte[] encrypt(Context context, String data, String password) { return encryptData(data.getBytes(), retrieveIv(context), deriveKeySecurely(context, password, KEY_SIZE)); } /** * 解密数据 * @param data 待解密的数据 * @param password 密钥 * @return 已解密的数据 */ public static byte[] decrypt(Context context, byte[] data, String password) { return decryptData(data, retrieveIv(context), deriveKeySecurely(context, password, KEY_SIZE)); }
使用方法:
调用AESUtil.encrypt(Context context, String data, String password)
来加密数据,调用AESUtil.decrypt(Context context, byte[] data, String password)
来解密数据。
Enjoy it
转载地址: http://celerysoft.github.io/2016-09-14.html
0 0
- Android N中不再支持“Crypto”的解决方案
- Security "Crypto" provider deprecated in Android N
- 在HTML5中不再支持的script的属性
- html5中不再支持table的cellspacing和cellpadding属性
- html5中不再支持table的cellspacing和cellpadding属
- html5中不再支持table的cellspacing和cellpadding属性
- html5中不再支持table的cellspacing和cellpadding属性
- python中Crypto的注意事项
- 作业不再执行的解决方案
- Google将不再支持Android Eclipse Tools
- Google将不再支持Android Eclipse Tools
- Android Studio支持Java1.8的解决方案
- Android中canvas.drawText()无法使用\r\n换行的解决方案
- Android N系统CTS verifier中cross profile相关测试项fail的解决方案
- IE8的getElementById不再支持name属性
- directx10不再支持.x文件的解决办法
- 【新版】VC中全局变量的使用总结(N种方法,看完就不再疑惑啦!)
- Android 6.0 的 SDK不再支持 Apache HTTP client而改用HttpURLConnection
- C++ 容器 new 删除问题
- 动画开源库NineOldAndroids的使用
- 怎么把XMind制作的甘特图导出为PDF
- laravel5.1出现No supported encrypter found错误的解决办法
- openwrt: br-lan: reveived packet on eth0 with own address as source address
- Android N中不再支持“Crypto”的解决方案
- JavaWeb从入门到精通(六)-自定义标签
- JVM
- SQL Server 2016 SP_SpaceUsed 新参数@OneResultSet
- Linux kernel 中断之proc接口之irq
- Matlab求点到你直线的垂直距离
- JS基础--输入框获取焦点
- windows下安装gensim
- asp.net 页面设计