Objective:
Recently studied the Android SQLite database and data sharing between contentprovider programs, we clearly know SQLite database default storage location Data/data/pakage/database directory, There is no security for a mobile phone that already has root, and once exploited will result in a leak of database data, so how can we avoid this? We try to encrypt the database.
Select encryption Scheme:
1.) The first programme
We can name the database for the data, table name, column name on the line MD5, encryption of stored data, such as AES encryption (encryption of the Android data encrypted Aes), when the query to decrypt the data, this way can not say bad, but the use of it can imagine the degree of trouble it brings.
2.) The second type of programme
Using Third-party encryption Open Source Library, looked for many kinds of Android database encryption scheme, finally selected Sqlcipher this open source framework, then see how sqlcipher use.
Sqlcipher Introduction:
Sqlcipher is an open source database that expands on the base of SQLite, and Sqlcipher has a small footprint, so it is very suitable for the embedded application database protection, which is very suitable for mobile development.
Advantage:
- High encryption performance, low overhead, as long as the cost of 5-15% is used to encrypt
- Completely do database 100% encryption
- Good encryption Method (CBC encryption mode)
- Easy to use, to achieve application level encryption
- An algorithm with OpenSSL encryption library
Sqlcipher Use mode:
1. Add the following code to the Build.gradle text, currently using the latest version 3.4.0
dependencies {
compile ' net.zetetic:android-database-sqlcipher:3.4.0 '
}
2.) Create a sqliteopenhelper note next so all the classes that refer to Net.sqlcipher.database for SQLite related classes
Import android.content.Context;
Import android.util.Log;
Import net.sqlcipher.SQLException;
Import net.sqlcipher.database.SQLiteDatabase;
Import net.sqlcipher.database.SQLiteOpenHelper;
Public class DBCipherHelper extends SQLiteOpenHelper {
Private static final String TAG = "DatabaseHelper";
Private static final String DB_NAME = "test_cipher_db";//database name
Public static final String DB_PWD="whoislcj";//database password
Public static String TABLE_NAME = "person";// table name
Public static String FIELD_ID = "id";// column name
Public static String FIELD_NAME= "name";// column name
Private static final int DB_VERSION = 1; // database version
Public DBCipherHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
Super(context, name, factory, version);
/ / can not be ignored for so library loading
SQLiteDatabase.loadLibs(context);
}
Public DBCipherHelper(Context context) {
This(context, DB_NAME, null, DB_VERSION);
}
/**
* Create a database
* @param db
*/
@Override
Public void onCreate(SQLiteDatabase db) {
/ / Create a table
createTable(db);
}
Private void createTable(SQLiteDatabase db){
String sql = "CREATE TABLE " + TABLE_NAME + "(" + FIELD_ID + " integer primary key autoincrement , " + FIELD_NAME + " text not null);";
Try {
db.execSQL(sql);
} catch (SQLException e) {
Log.e(TAG, "onCreate " + TABLE_NAME + "Error" + e.toString());
Return;
}
}
/**
* Database upgrade
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
Public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Note: sqlitedatabase.loadlibs (context); This must not forget to call
3.) Create a Dbciphermanager database management
The actual implementation of the traditional sqliteopenhelper are exactly the same, different places in getting the database handle
Traditional way:
Get writable database
sqlitedatabase db = Dbhelper.getwritabledatabase ();
Get a readable database
sqlitedatabase db = Dbhelper.getreadabledatabase ();
Now the way: you need to pass in a password, this password is the secret key for encryption
Get write database
sqlitedatabase db = Dbhelper.getwritabledatabase (dbcipherhelper.db_pwd);
Gets the readable database
sqlitedatabase db = Dbhelper.getreadabledatabase (DBCIPHERHELPER.DB_PWD);
The next step is to implement the specific:
Import android.content.ContentValues;
Import android.content.Context;
Import android.util.Log;
Import net.sqlcipher.Cursor;
Import net.sqlcipher.SQLException;
Import net.sqlcipher.database.SQLiteDatabase;
/**
* Database Manager - Provides database encapsulation
*
*/
Public class DBCipherManager {
Private static final String TAG = "DatabaseManager";
// static reference
Private volatile static DBCipherManager mInstance;
// DatabaseHelper
Private DBCipherHelper dbHelper;
Private DBCipherManager(Context context) {
dbHelper = new DBCipherHelper(context.getApplicationContext());
}
/**
* Get a singleton reference
*
* @param context
* @return
*/
Public static DBCipherManager getInstance(Context context) {
DBCipherManager inst = mInstance;
If (inst == null) {
Synchronized (DBCipherManager.class) {
Inst = mInstance;
If (inst == null) {
Inst = new DBCipherManager(context);
mInstance = inst;
}
}
}
Return inst;
}
/**
* Insert data
*/
Public void insertData(String name) {
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
/ / Generate the key value to be modified or inserted
ContentValues cv = new ContentValues();
Cv.put(DBCipherHelper.FIELD_NAME, name);
// insert operation
Db.insert(DBCipherHelper.TABLE_NAME, null, cv);
/ / Close the database
Db.close();
}
/**
* Transaction bulk insert is not turned on
* @param testCount
*/
Public void insertDatasByNomarl(int testCount){
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
For(int i =0;i<testCount;i++ ){
/ / Generate the key value to be modified or inserted
ContentValues cv = new ContentValues();
Cv.put(DBCipherHelper.FIELD_NAME, String.valueOf(i));
// insert operation
Db.insert(DBCipherHelper.TABLE_NAME, null, cv);
Log.e(TAG, "insertDatasByNomarl");
}
/ / Close the database
Db.close();
}
/**
* Test open transaction bulk insert
* @param testCount
*/
Public void insertDatasByTransaction(int testCount){
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
db.beginTransaction(); //Manually set the start transaction
Try{
/ / Batch processing operations
For(int i =0;i<testCount;i++ ){
/ / Generate the key value to be modified or inserted
ContentValues cv = new ContentValues();
Cv.put(DBCipherHelper.FIELD_NAME, String.valueOf(i));
// insert operation
Db.insert(DBCipherHelper.TABLE_NAME, null, cv);
Log.e(TAG, "insertDatasByTransaction");
}
db.setTransactionSuccessful(); //Set the transaction to succeed, if it is not set, it will automatically roll back and not submit.
}catch(Exception e){
}finally{
db.endTransaction(); //Processing completed
/ / Close the database
Db.close();
}
}
/**
* delete data
*/
Public void deleteData(String name) {
/ / Generate conditional statements
StringBuffer whereBuffer = new StringBuffer();
whereBuffer.append(DBCipherHelper.FIELD_NAME).append(" = ").append("'").append(name).append("'");
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
// delete operation
Db.delete(DBCipherHelper.TABLE_NAME, whereBuffer.toString(), null);
/ / Close the database
Db.close();
}
/**
* Delete all data
*/
Public void deleteDatas()
{
String sql="delete from "+ DBCipherHelper.TABLE_NAME;
execSQL(sql);
}
/**
* update data
*/
Public void updateData(String name) {
/ / Generate conditional statements
StringBuffer whereBuffer = new StringBuffer();
whereBuffer.append(DBCipherHelper.FIELD_NAME).append(" = ").append("'").append(name).append("'");
/ / Generate the key value to be modified or inserted
ContentValues cv = new ContentValues();
Cv.put(DBCipherHelper.FIELD_NAME, name+name);
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
// update operation
Db.update(DBCipherHelper.TABLE_NAME, cv, whereBuffer.toString(), null);
/ / Close the database
Db.close();
}
/**
* Specify conditional query data
*/
Public void queryDatas(String name){
/ / Generate conditional statements
StringBuffer whereBuffer = new StringBuffer();
whereBuffer.append(DBCipherHelper.FIELD_NAME).append(" = ").append("'").append(name).append("'");
/ / Specify which columns of data to query
String[] columns = {DBCipherHelper.FIELD_NAME};
/ / Get a readable database
SQLiteDatabase db = dbHelper.getReadableDatabase(DBCipherHelper.DB_PWD);
/ / Query the database
Cursor cursor = null;
Try {
Cursor = db.query(DBCipherHelper.TABLE_NAME, columns, whereBuffer.toString(), null, null, null, null);
While (cursor.moveToNext()) {
Int count = cursor.getColumnCount();
String columName = cursor.getColumnName(0);
String tname = cursor.getString(0);
Log.e(TAG, "count = " + count + " columName = " + columName + " name = " +tname);
}
If (cursor != null) {
Cursor.close();
}
} catch (SQLException e) {
Log.e(TAG, "queryDatas" + e.toString());
}
/ / Close the database
Db.close();
}
/**
* Query all data
*/
Public void queryDatas(){
/ / Specify which columns of data to query
String[] columns = {DBCipherHelper.FIELD_NAME};
/ / Get a readable database
SQLiteDatabase db = dbHelper.getReadableDatabase(DBCipherHelper.DB_PWD);
/ / Query the database
Cursor cursor = null;
Try {
Cursor = db.query(DBCipherHelper.TABLE_NAME, columns, null, null, null, null, null);//Get data cursor
While (cursor.moveToNext()) {
Int count = cursor.getColumnCount();
String columeName = cursor.getColumnName(0);//Get the table structure column name
String name = cursor.getString(0);//Get table structure column data
Log.e(TAG, "count = " + count + " columName = " + columeName + " name = " +name);
}
/ / Close the cursor to prevent memory leaks
If (cursor != null) {
Cursor.close();
}
} catch (SQLException e) {
Log.e(TAG, "queryDatas" + e.toString());
}
/ / Close the database
Db.close();
}
/**
* Execute sql statement
*/
Private void execSQL(String sql){
/ / Get the write database
SQLiteDatabase db = dbHelper.getWritableDatabase(DBCipherHelper.DB_PWD);
/ / Direct execution of the sql statement
db.execSQL(sql);//or
/ / Close the database
Db.close();
}
}
}
4.) specifically how to call
Empty data
dbciphermanager.getinstance (mainactivity.this). Deletedatas ();
Insert data for
(int i = 0; i < i++) {
dbciphermanager.getinstance (mainactivity.this). InsertData ( String.valueof (i));
Delete Data
dbciphermanager.getinstance (mainactivity.this). DeleteData (String.valueof (5));
Update Data
dbciphermanager.getinstance (mainactivity.this). UpdateData (String.valueof (3));
Query data
dbciphermanager.getinstance (mainactivity.this). Querydatas ();
5.) Transactional support in the same way as traditional
Get write database
sqlitedatabase db = Dbhelper.getwritabledatabase ();
Db.begintransaction (); Manually set start transaction
try{
//Handling Bulk operations for
(int i =0;i<testcount;i++) {
//Generate key value Contentvalues CV to be modified or inserted
New Contentvalues ();
Cv.put (Dbhelper.field_name, string.valueof (i));
Insert Operation
Db.insert (dbhelper.table_name, NULL, CV);
}
Db.settransactionsuccessful (); Set transaction success without setting automatically rollback uncommitted
}catch (Exception e) {
}finally{
db.endtransaction ();//Process completion
//Shutdown database
db.close ();
}
Summarize:
Sqlcipher Use summary end of this.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.