Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android使用SQLCipher加解密數據庫

Android使用SQLCipher加解密數據庫

編輯:Android開發實例

我們都知道,Android系統內置了SQLite數據庫,並且提供了一整套的API用於對數據庫進行增刪改查操作。數據庫存儲是我們經常會使用到的一種存儲方式,相信大多數朋友對它的使用方法都已經比較熟悉了吧。在Android中,我們既可以使用原生的SQL語句來對數據進行操作,也可以使用Android API提供的CRUD方法來對數據庫進行操作,兩種方式各有特點,選擇使用哪一種就全憑個人喜好了。
 

不過,使用SQLite來存儲數據卻存在著一個問題。因為大多數的Android手機都是Root過的,而Root過的手機都可以進入到/data/data/<package_name>/databases目錄下面,在這裡就可以查看到數據庫中存儲的所有數據。如果是一般的數據還好,但是當涉及到一些賬號密碼,或者聊天內容的時候,我們的程序就會面臨嚴重的安全漏洞隱患。那麼今天,就讓我們一起研究一下如何借助SQLCipher來解決這個安全性問題。
 

SQLCipher是一個在SQLite基礎之上進行擴展的開源數據庫,它主要是在SQLite的基礎之上增加了數據加密功能,如果我們在項目中使用它來存儲數據的話,就可以大大提高程序的安全性。SQLCipher支持很多種不同的平台,這裡我們要學習的自然是Android中SQLCipher的用法了。

下面我們就開始吧,首先要把Android項目所依賴的SQLCipher工具包下載下來,下載地址是:

https://s3.amazonaws.com/sqlcipher/SQLCipher+for+Android+v2.2.2.zip
 

接著解壓這個工具包,會看到裡面有assets和libs這兩個目錄,稍後需要將這兩個目錄中的內容添加到Android項目當中。那麼現在我們就來新建一個Android項目,項目名就叫SQLCipherTest。
 

觀察SQLCipherTest的項目結構,發現裡面也分別有一個assets目錄和一個libs目錄,那麼現在就可以把SQLCipher工具包中這兩個目錄裡的內容復制過來。並不需要復制全部文件,選擇必要的文件進行復制就可以了,完成以後項目結構圖如下所示,圖中顯示的文件都是必要的。
 

                            
 

到這裡准備工作就全部完成了,接下來我們開始編寫代碼。首先創建一個MyDatabaseHelper繼承自SQLiteOpenHelper,注意這裡使用的並不是Android API中的SQLiteOpenHelper,而是net.sqlcipher.database包下的SQLiteOpenHelper,代碼如下所示:

  1. import android.content.Context;  
  2. import net.sqlcipher.database.SQLiteDatabase;  
  3. import net.sqlcipher.database.SQLiteDatabase.CursorFactory;  
  4. import net.sqlcipher.database.SQLiteOpenHelper;  
  5.  
  6. public class MyDatabaseHelper extends SQLiteOpenHelper {  
  7.       
  8.     public static final String CREATE_TABLE = "create table Book(name text, pages integer)";  
  9.  
  10.     public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) {  
  11.         super(context, name, factory, version);  
  12.     }  
  13.  
  14.     @Override 
  15.     public void onCreate(SQLiteDatabase db) {  
  16.         db.execSQL(CREATE_TABLE);  
  17.     }  
  18.  
  19.     @Override 
  20.     public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {  
  21.  
  22.     }  
  23.  
  24. }  

除了引入的包不一樣了,其它的用法和傳統的SQLiteOpenHelper都是完全相同的。可以看到,我們在onCreate()方法中創建了一張Book表,Book表裡有name和pages這兩個列。

 

接著,打開或新建activity_main.xml作為程序的主布局文件,代碼如下所示:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  2.     android:layout_width="match_parent" 
  3.     android:layout_height="match_parent" 
  4.     android:orientation="vertical" > 
  5.       
  6.     <Button   
  7.         android:id="@+id/add_data" 
  8.         android:layout_width="match_parent" 
  9.         android:layout_height="wrap_content" 
  10.         android:text="添加數據" 
  11.         /> 
  12.       
  13.     <Button   
  14.         android:id="@+id/query_data" 
  15.         android:layout_width="match_parent" 
  16.         android:layout_height="wrap_content" 
  17.         android:text="查詢數據" 
  18.         /> 
  19.  
  20. </LinearLayout> 


這裡只是簡單地放置了兩個按鈕,分別用於添加和查詢數據。接下來打開或新建MainActivity作為程序主Activity,代碼如下所示:

  1. public class MainActivity extends Activity {  
  2.       
  3.     private SQLiteDatabase db;  
  4.  
  5.     @Override 
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.         SQLiteDatabase.loadLibs(this);  
  10.         MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "demo.db", null, 1);  
  11.         db = dbHelper.getWritableDatabase("secret_key");  
  12.         Button addData = (Button) findViewById(R.id.add_data);  
  13.         Button queryData = (Button) findViewById(R.id.query_data);  
  14.         addData.setOnClickListener(new OnClickListener() {  
  15.             @Override 
  16.             public void onClick(View v) {  
  17.                 ContentValues values = new ContentValues();  
  18.                 values.put("name", "達芬奇密碼");  
  19.                 values.put("pages", 566);  
  20.                 db.insert("Book", null, values);  
  21.             }  
  22.         });  
  23.         queryData.setOnClickListener(new OnClickListener() {  
  24.             @Override 
  25.             public void onClick(View v) {  
  26.                 Cursor cursor = db.query("Book", null, null, null, null, null, null);  
  27.                 if (cursor != null) {  
  28.                     while (cursor.moveToNext()) {  
  29.                         String name = cursor.getString(cursor.getColumnIndex("name"));  
  30.                         int pages = cursor.getInt(cursor.getColumnIndex("pages"));  
  31.                         Log.d("TAG", "book name is " + name);  
  32.                         Log.d("TAG", "book pages is " + pages);  
  33.                     }  
  34.                 }  
  35.                 cursor.close();  
  36.             }  
  37.         });  
  38.     }  
  39.  
  40. }  

可以看到,在onCreate()方法中首先調用了SQLiteDatabase的loadLibs()靜態方法將SQLCipher所依賴的so庫加載進來,注意這裡使用的是net.sqlcipher.database包下的SQLiteDatabase。然後我們創建了MyDatabaseHelper的實例,並調用getWritableDatabase()方法去獲取SQLiteDatabase對象。這裡在調用getWritableDatabase()方法的時候傳入了一個字符串參數,它就是SQLCipher所依賴的key,在對數據庫進行加解密的時候SQLCipher都將使用這裡指定的key。

 

在添加數據按鈕的點擊事件裡面,我們通過ContentValues構建了一條數據,然後調用SQLiteDatabase的insert()方法將這條數據插入到Book表中。

在查詢數據按鈕的點擊事件裡面,我們調用SQLiteDatabase的query()方法來查詢Book表中的數據,查詢到的結果會存放在Cursor對象中,注意這裡使用的是net.sqlcipher包下的Cursor。然後對Cursor對象進行遍歷,並將查詢到的結果打印出來。
 

現在運行一下程序,先點擊添加數據按鈕,再點擊查詢數據按鈕,剛剛添加的那條數據就應該在控制台裡打印出來了。
 

有沒有感覺到使用SQLCipher提供的API和使用Android原生的數據庫API,操作起來幾乎是一模一樣的。沒錯,SQLCipher對Android SDK中所有與數據庫相關的API都制作了一份鏡像,使得開發者可以像操作普遍的數據庫文件一樣來操作SQLCipher,而所有的數據加解密操作,SQLCipher都在背後幫我們處理好了。
 

話說寫到這裡,我們都一直還沒體驗一下SQLCipher加密後的效果呢,現在就來看一看吧,首先通過命令行的方式來訪問demo.db這個數據庫文件:
 

 

adb shell
cd /data/data/com.example.sqlciphertest/databases
sqlite3 -line demo.db
.table

嘗試查看demo.db中的所有表,結果返回如下圖所示:

  

從圖中可以看出,當執行.table命令的時候被拒絕了,原因是數據庫文件已加密。
 

除了使用命令行的方式,我們還可以嘗試使用Root Explorer來打開數據庫文件,結果如下圖所示:
 

                                        

意料之中,果然打開失敗了。這就足以說明,目前數據庫中的數據是非常安全的,只有在應用程序裡通過SQLCipher提供的API才可以訪問到數據庫裡的數據,使用其它的方式都無法獲取其數據。
 

需要提醒的一點是,項目中引入了SQLCipher之後,會讓你的程序體積驟然增加,打成APK後大概會變大好幾M,是更側重於文件大小,還是更側重於程序安全,你應該根據具體的需求做出合適的判斷。
 

源碼下載,請點擊這裡
 

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