現在項目里面有一個需求,本項目里面下載的視頻和文檔都不允許通過其他的播放器播放,在培訓機構里面這樣的需求很多。防止有人交一份錢,把所有的課件就拷給了別人。這樣的事情培訓機構肯定是不愿意的。現在我項目里面也出了這么個需求。下面介紹一下我的實現。
文件加解密的流程及原理
1、加密方法:存儲文件時,從輸入流中截取文件的字節數組,對字節數組進行加密,至于加密的方式和算法就可以視需求而定了,然后把加密后的字節數組寫入到文件中,最后生成加密后的文件;
2、解密方法:同加密方法一樣,只不過是對字節數據進行解密,最后生成明文文件;
3、加密算法:Android系統本身引入了javax包的Cipher類,這個類里提供了各種各樣的通用的加密方式,如AES對稱加密等;該程序中有個CipherUtil工具類,里面有一些簡單的使用Cipher進行AES加解密的方法;當然最好還是好好學習一下Cipher類的使用;
4、注意事項:
主要代碼
/**自定義實現簡單的文件加密解密工具 * Created by zhangshuo on 2016/6/28. */ public class CustomFileCipherUtil { /** * 加密后的文件的后綴 */ public static final String CIPHER_TEXT_SUFFIX = ".cipher"; /** * 加解密時以32K個字節為單位進行加解密計算 */ private static final int CIPHER_BUFFER_LENGHT = 32 * 1024; /** * 加密,這里主要是演示加密的原理,沒有用什么實際的加密算法 * * @param filePath 明文文件絕對路徑 * @return */ public static boolean encrypt(String filePath, CipherListener listener) { try { long startTime = System.currentTimeMillis(); File f = new File(filePath); RandomAccessFile raf = new RandomAccessFile(f, "rw"); long totalLenght = raf.length(); FileChannel channel = raf.getChannel(); long multiples = totalLenght / CIPHER_BUFFER_LENGHT; long remainder = totalLenght % CIPHER_BUFFER_LENGHT; MappedByteBuffer buffer = null; byte tmp; byte rawByte; //先對整除部分加密 for(int i = 0; i < multiples; i++){ buffer = channel.map( FileChannel.MapMode.READ_WRITE, i * CIPHER_BUFFER_LENGHT, (i + 1) * CIPHER_BUFFER_LENGHT); //此處的加密方法很簡單,只是簡單的異或計算 for (int j = 0; j < CIPHER_BUFFER_LENGHT; ++j) { rawByte = buffer.get(j); tmp = (byte) (rawByte ^ j); buffer.put(j, tmp); if(null != listener){ listener.onProgress(i * CIPHER_BUFFER_LENGHT + j, totalLenght); } } buffer.force(); buffer.clear(); } //對余數部分加密 buffer = channel.map( FileChannel.MapMode.READ_WRITE, multiples * CIPHER_BUFFER_LENGHT, multiples * CIPHER_BUFFER_LENGHT + remainder); for (int j = 0; j < remainder; ++j) { rawByte = buffer.get(j); tmp = (byte) (rawByte ^ j); buffer.put(j, tmp); if(null != listener){ listener.onProgress(multiples * CIPHER_BUFFER_LENGHT + j, totalLenght); } } buffer.force(); buffer.clear(); channel.close(); raf.close(); //對加密后的文件重命名,增加.cipher后綴 // f.renameTo(new File(f.getPath() + CIPHER_TEXT_SUFFIX)); Log.d("加密用時:", (System.currentTimeMillis() - startTime) /1000 + "s"); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 解密,這里主要是演示加密的原理,沒有用什么實際的加密算法 * * @param filePath 密文文件絕對路徑,文件需要以.cipher結尾才會認為其實可解密密文 * @return */ public static boolean decrypt(String filePath, CipherListener listener) { try { long startTime = System.currentTimeMillis(); File f = new File(filePath); // if(!f.getPath().toLowerCase().endsWith(CIPHER_TEXT_SUFFIX)){ // //后綴不同,認為是不可解密的密文 // return false; // } RandomAccessFile raf = new RandomAccessFile(f, "rw"); long totalLenght = raf.length(); FileChannel channel = raf.getChannel(); long multiples = totalLenght / CIPHER_BUFFER_LENGHT; long remainder = totalLenght % CIPHER_BUFFER_LENGHT; MappedByteBuffer buffer = null; byte tmp; byte rawByte; //先對整除部分解密 for(int i = 0; i < multiples; i++){ buffer = channel.map( FileChannel.MapMode.READ_WRITE, i * CIPHER_BUFFER_LENGHT, (i + 1) * CIPHER_BUFFER_LENGHT); //此處的解密方法很簡單,只是簡單的異或計算 for (int j = 0; j < CIPHER_BUFFER_LENGHT; ++j) { rawByte = buffer.get(j); tmp = (byte) (rawByte ^ j); buffer.put(j, tmp); if(null != listener){ listener.onProgress(i * CIPHER_BUFFER_LENGHT + j, totalLenght); } } buffer.force(); buffer.clear(); } //對余數部分解密 buffer = channel.map( FileChannel.MapMode.READ_WRITE, multiples * CIPHER_BUFFER_LENGHT, multiples * CIPHER_BUFFER_LENGHT + remainder); for (int j = 0; j < remainder; ++j) { rawByte = buffer.get(j); tmp = (byte) (rawByte ^ j); buffer.put(j, tmp); if(null != listener){ listener.onProgress(multiples * CIPHER_BUFFER_LENGHT + j, totalLenght); } } buffer.force(); buffer.clear(); channel.close(); raf.close(); //對加密后的文件重命名,增加.cipher后綴 // f.renameTo(new File(f.getPath().substring(f.getPath().toLowerCase().indexOf(CIPHER_TEXT_SUFFIX)))); Log.d("解密用時:", (System.currentTimeMillis() - startTime) / 1000 + "s"); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 用于加解密進度的監聽器 */ public interface CipherListener{ void onProgress(long current, long total); } } 效果如圖:

代碼就是這么多,都有注釋。以后再有這種需求可以直接用。以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答