捣鼓了两个星期的加密解密文件夹,一开始是用异或,后来觉得太简单换成了AES,结果一堆bug,上网查了很多,现在将这个最终的版本记录下来。已经在android 5.1系统上测试过,是可以的。
/** * 初始化 AES Cipher * @param sKey * @param cipherMode * @return */ public static Cipher initAESCipher (String sKey, int cipherMode) throws Exception { //创建Key gen KeyGenerator keyGenerator = null; Cipher cipher = null; keyGenerator = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG" ,"Crypto"); sr.setSeed(sKey.getBytes("UTF-8")); keyGenerator.init(128,sr); SecretKey secretKey = keyGenerator.generateKey(); byte[] codeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(codeFormat, "AES"); cipher = Cipher.getInstance("AES"); //初始化 cipher.init(cipherMode, key); return cipher; }
/** * 对文件进行AES加密 * @param sourceFile * @param fileType * @param sKey * @return */ public static File encryptFile(File sourceFile,String fileType, String sKey) throws Exception { //新建临时加密文件 File encrypfile = null; InputStream inputStream = null; OutputStream outputStream = null; inputStream = new FileInputStream(sourceFile); encrypfile = new File(fileType); outputStream = new FileOutputStream(encrypfile); Cipher cipher = initAESCipher(sKey,Cipher.ENCRYPT_MODE); //以加密流写入文件 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(); sourceFile.delete(); inputStream.close(); outputStream.close(); Log.d("MainActivity", "加密成功"); return encrypfile; }
/** * AES方式解密文件 * @param sourceFile * @return */ public static File decryptFile(File sourceFile,String fileType,String sKey) throws Exception { File decryptFile = null; InputStream inputStream = null; OutputStream outputStream = null; decryptFile = new File(fileType);; Cipher cipher = initAESCipher(sKey,Cipher.DECRYPT_MODE); inputStream = new FileInputStream(sourceFile); outputStream = new FileOutputStream(decryptFile); 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(); sourceFile.delete(); inputStream.close(); outputStream.close(); Log.d("MainActivity", "解密成功" ); return decryptFile; }
如果要加密解密文件夹,只需要遍历进行加密解密即可:
public static void encryptFolder(String strPath){ File dir = new File(strPath); File[] files = dir.listFiles(); if (files != null){ for (int i=0; i<files.length;i++){ String fileName = files[i].getName(); if (files[i].isDirectory()){ encryptFolder(files[i].getAbsolutePath()); }else if(fileName.contains(".lock")){ //表明该文件已经加密过了,不需要再次加密 continue; }else{ File file = new File(files[i].getAbsolutePath()); try { encryptFile(file,files[i].getAbsolutePath()+".lock", constants.CryptConstant.PRIVATE_AES_KEY); } catch (Exception e) { e.printStackTrace(); Log.d("MainActivity","加密出错"+e.getMessage()); } } } } } public static void decryptFolder(String strPath){ File dir = new File(strPath); File[] files = dir.listFiles(); if (files != null){ for (int i=0; i<files.length;i++){ String fileName = files[i].getName(); if (files[i].isDirectory()){ decryptFolder(files[i].getAbsolutePath()); }else { //只有是加密文件才进行解密 if (files[i].getAbsolutePath().contains(".lock")){ File file = new File(files[i].getAbsolutePath()); try { decryptFile(file,files[i].getAbsolutePath().replace(".lock",""), constants.CryptConstant.PRIVATE_AES_KEY); } catch (Exception e) { e.printStackTrace(); Log.d("MainActivity", "解密出错" + e.getMessage()); } } } } } }
/** * 生成指定字符串的密钥 * @param secret 要生成密钥的字符串 * @return secretKey 生成后的密钥 * @throws GeneralSecurityException */ private static Key getKey(String secret) throws GeneralSecurityException { KeyGenerator kgen = KeyGenerator.getInstance(type); try { SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG" ,"Crypto"); sr.setSeed(secret.getBytes("UTF-8")); kgen.init(128,sr); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } SecretKey secretKey = kgen.generateKey(); return secretKey; }
public static String encryString(String privateKey,String content){ Key key = null; try { key = getKey(privateKey); Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] byteContent = content.getBytes("UTF-8"); byte[] result=cipher.doFinal(byteContent); String s = Base64.encodeToString(result, Base64.DEFAULT); return s; } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public static String decryptString(String privateKey,String content){ Key key = null; try { key = getKey(privateKey); Cipher cipher = Cipher.getInstance(type + "/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decodeValue = Base64.decode(content, Base64.DEFAULT); byte[] result=cipher.doFinal(decodeValue); return new String(result,"UTF-8"); } catch (GeneralSecurityException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; }