java和android文件加密小结
最近遇到一个文件加密的问题,自己读写的,安全性虽然还可以,但是速度慢,影响体验。
Cipher虽然速度相当快,但是android和java有某些api存在不兼容;
问题解决:
方法引用自:https://www.jianshu.com/p/2aa5e1a1df1a
还是使用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; } }