最近遇到一個文件加密的問題,本身讀寫的,安全性雖然還能夠,可是速度慢,影響體驗。java
Cipher雖然速度至關快,可是android和java有某些api存在不兼容;android
問題解決:算法
方法引用自:https://www.jianshu.com/p/2aa5e1a1df1aapi
仍是使用cipher,算法中用到了一個填充向量,即VIPARA, 這個向量的取值是不固定的,可是加密祕鑰必須爲16個字節,譬如「abcdefghabcdefgh」安全
package com.example; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.CipherInputStream; import javax.crypto.CipherOutputStream; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class MyCipher { public static final String VIPARA = "0102030405060708"; private static final String _FILE_NAME_OF_SECRET_ = "file-secret"; private static final String _FILE_LOC_FILE_NAME_ = "file-local"; private static final String _SOURCE_FILE_PATH_ = "path" + File.separator + _FILE_LOC_FILE_NAME_; private static final String _OUTPUT_FILE_PATH_ = "path" + File.separator + _FILE_NAME_OF_SECRET_; public static void main(String[] args) { encryptFile(_FILE_NAME_OF_SECRET_, _SOURCE_FILE_PATH_, _OUTPUT_FILE_PATH_); } /** * 初始化 AES Cipher * * @param sKey * @param cipherMode * @return */ private static Cipher initAESCipher(String sKey, int cipherMode) { //建立Key gen KeyGenerator keyGenerator = null; Cipher cipher = null; try { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); SecretKeySpec key = new SecretKeySpec(sKey.getBytes(), "AES"); cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(cipherMode, key, zeroIv); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } return cipher; } /** * 對文件進行AES加密 * * @param key * @param sourceFilePath * @param destFilePath * @return */ public static File encryptFile(String key, String sourceFilePath, String destFilePath) { System.out.printf(sourceFilePath); FileInputStream in = null; FileOutputStream out = null; File destFile = null; File sourceFile = null; try { sourceFile = new File(sourceFilePath); destFile = new File(destFilePath); if (sourceFile.exists() && sourceFile.isFile()) { if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); in = new FileInputStream(sourceFile); out = new FileOutputStream(destFile); Cipher cipher = initAESCipher(key, Cipher.ENCRYPT_MODE); //以加密流寫入文件 CipherInputStream cipherInputStream = new CipherInputStream(in, cipher); byte[] cache = new byte[1024]; int nRead = 0; while ((nRead = cipherInputStream.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } cipherInputStream.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return destFile; } /** * AES方式解密文件 * * @param key * @param sourceFilePath * @param destFilePath * @return */ public static File decryptFile(String key, String sourceFilePath, String destFilePath) { FileInputStream in = null; FileOutputStream out = null; File destFile = null; File sourceFile = null; try { sourceFile = new File(sourceFilePath); destFile = new File(destFilePath); if (sourceFile.exists() && sourceFile.isFile()) { if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); in = new FileInputStream(sourceFile); out = new FileOutputStream(destFile); Cipher cipher = initAESCipher(key, Cipher.DECRYPT_MODE); CipherOutputStream cipherOutputStream = new CipherOutputStream(out, cipher); byte[] buffer = new byte[1024]; int r; while ((r = in.read(buffer)) >= 0) { cipherOutputStream.write(buffer, 0, r); } cipherOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } try { out.close(); } catch (IOException e) { e.printStackTrace(); } } return destFile; } }