Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android中對文件加密解密的實現

android中對文件加密解密的實現

編輯:關於Android編程

現在項目裡面有一個需求,本項目裡面下載的視頻和文檔都不允許通過其他的播放器播放,在培訓機構裡面這樣的需求很多。防止有人交一份錢,把所有的課件就拷給了別人。這樣的事情培訓機構肯定是不願意的。現在我項目裡面也出了這麼個需求。下面介紹一下我的實現。

文件加解密的流程及原理

1、加密方法:存儲文件時,從輸入流中截取文件的字節數組,對字節數組進行加密,至於加密的方式和算法就可以視需求而定了,然後把加密後的字節數組寫入到文件中,最後生成加密後的文件;

2、解密方法:同加密方法一樣,只不過是對字節數據進行解密,最後生成明文文件;

3、加密算法:Android系統本身引入了javax包的Cipher類,這個類裡提供了各種各樣的通用的加密方式,如AES對稱加密等;該程序中有個CipherUtil工具類,裡面有一些簡單的使用Cipher進行AES加解密的方法;當然最好還是好好學習一下Cipher類的使用;

4、注意事項:

  1. 如何判斷一個文件是加密後的文件,最簡單的方法就是對加密後的文件統一增加一個後綴名,然後在解密之後將這個後綴名去除,還原回原有文件格式;如:密文文件的統一後綴名為“.cipher”,明文文件名為"測試.txt",加密後的密文文件應該為“測試.txt.cipher”;
  2. 加密文件時還有一個重要的注意事項,就是加密後的密文和明文的長度是否相同,如果文件時一次讀取出所有字節數組進行加密的話不用擔心這個問題,但是當對文件分次讀取加密或分段加密的話,就不得不考慮這個問題了,最方便的方法就是保證明文和加密後的密文長度相同;如果長度不同,由於是分段加密的,密文是由一段一段子密文拼接成的,解密時會找不到每段子密文,因為不知道每段子密文的長度是多少;

主要代碼

/**自定義實現簡單的文件加密解密工具 
 * 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); 
  } 
} 

效果如圖:

代碼就是這麼多,都有注釋。以後再有這種需求可以直接用。以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved