Android JNI環境下給SQLite引入加密模組
免費的SQLite開源源碼只給提供了兩個函數,只有實現這兩個函數才能實現資料庫整體加密。然後廢了點勁從網上找了一個已經實現好的開源庫http://sourceforge.net/projects/wxcode/files/Components/wxSQLite3/
然後大概寫一下如何把它整合到自己的so庫中。
首先下載源碼,找到sqlite3/secure/src下,把其中所有的檔案(除了sqlite3.def)拷貝到Android工程下的jni目錄下,然後開啟sqlite3.c檔案,在最前面添加一行代碼:
#define SQLITE_HAS_CODEC
在jni目錄下建立Android.mk檔案,輸入如下內容:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS) LOCAL_MODULE:= libsqlite3 LOCAL_SRC_FILES:= sqlite3secure.c #這裡寫的是相對路徑include $(BUILD_STATIC_LIBRARY) # 從這裡開始是so庫的聲明,我這裡使用了一個自動載入指令碼,只需要指定# MY_FILES_PATH就能自動載入所有的cpp和c檔案include $(CLEAR_VARS)LOCAL_MODULE := nativeMY_FILES_PATH := $(LOCAL_PATH)/ClassesMY_FILES_SUFFIX := %.cpp %.c# 遞迴遍曆目錄下的所有的檔案rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))# 擷取相應的源檔案MY_ALL_FILES := $(foreach src_path,$(MY_FILES_PATH), $(call rwildcard,$(src_path),*.*) ) MY_ALL_FILES := $(MY_ALL_FILES:$(MY_CPP_PATH)/./%=$(MY_CPP_PATH)%)MY_SRC_LIST := $(filter $(MY_FILES_SUFFIX),$(MY_ALL_FILES)) MY_SRC_LIST := $(MY_SRC_LIST:$(LOCAL_PATH)/%=%)# 去除字串的重複單詞define uniq = $(eval seen :=) $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_))) ${seen}endef# 遞迴遍曆擷取所有目錄MY_ALL_DIRS := $(dir $(foreach src_path,$(MY_FILES_PATH), $(call rwildcard,$(src_path),*/) ) )MY_ALL_DIRS := $(call uniq,$(MY_ALL_DIRS))#MY_ALL_DIRS := # 賦值給NDK編譯系統LOCAL_SRC_FILES := $(MY_SRC_LIST)LOCAL_C_INCLUDES := $(MY_ALL_DIRS)LOCAL_LDLIBS := -llog -ldlLOCAL_STATIC_LIBRARIES := libsqlite3 # 這裡添加靜態庫include $(BUILD_SHARED_LIBRARY)
在使用的時候,只需要
#include "sqlite3.h"
然後在open資料庫之後,調用如下兩個函數:
SQLITE_API int sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, /* The key */ int nKey /* The key length */);SQLITE_API int sqlite3_key_v2( sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, /* The key */ int nKey /* The key length */);
即可將資料庫加密。
需要注意的是,只能在建立資料庫後馬上調用以上兩個函數中的任意一個才能加密資料庫。當需要操作一個加密後的資料庫後,只需要在open資料庫之後調用一次該函數,即可正常操作資料庫。