Android data storage Sqlite uses SQLCipher database encryption practices, sqlitesqlcipher

Source: Internet
Author: User

Android data storage Sqlite uses SQLCipher database encryption practices, sqlitesqlcipher
Preface:

A recent study of Android Sqlite database (article address: http://www.cnblogs.com/whoislcj/p/5506294.html) and ContentProvider Program Data Sharing (http://www.cnblogs.com/whoislcj/p/5507928.html ), we clearly know the default storage location of the Sqlite database under the data/pakage/database directory, there is no security for the ROOT mobile phone, once used, database data may leak. So how can we avoid this? We try to encrypt the database.

Select an encryption scheme:

1.) solution 1

We can on the data database name, table name, column name md5, encryption of the stored data, such as aes encryption (http://www.cnblogs.com/whoislcj/p/5473030.html), the data is decrypted when the query, this method is not difficult to say, but you can imagine the troubles it brings.

2.) solution 2

Using a third-party open-source encrypted library, I found many Android database encryption solutions. Finally, I chose the open-source framework SQLCipher. Next I will look at how to use SqlCipher.

SQLCipher introduction:

SQLCipher is an open-source database that is extended based on SQLite. SQLCipher has a small footprint and performance. Therefore, it is very suitable for database protection of embedded applications and is very suitable for mobile development.

Advantages:

  • High encryption performance and low overhead, As long as 5-15% overhead is used for encryption
  • Fully implement database 100% Encryption
  • Adopt good encryption mode (CBC encryption mode)
  • Easy to use, application-level encryption
  • Algorithm provided by the OpenSSL encryption Library
SQLCipher usage: 1.) Add the following code in build. gradle. The latest version is 3.4.0.

dependencies {    compile 'net.zetetic:android-database-sqlcipher:3.4.0'}
2.) create a SQLiteOpenHelper. Note that the related Sqlite classes will reference net. sqlcipher. database 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); // so Database loading SQLiteDatabase cannot be ignored. loadLibs (context);} public DBCipherHelper (Context context) {this (context, DB_NAME, null, DB_VERSION );} /*** create database ** @ param db */@ Override public void onCreate (SQLiteDatabase db) {// create 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.exe cSQL (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); Do not forget to call

3.) create a DBCipherManager database for management.

The specific implementation of the traditional SQLiteOpenHelper is exactly the same, and different places are where the database handle is obtained

Traditional methods:

// Obtain the writable database SQLiteDatabase db = dbHelper. getWritableDatabase (); // obtain the readable database SQLiteDatabase db = dbHelper. getReadableDatabase ();

The current method: You need to input a password, which is the key used for encryption.

// Obtain the written database SQLiteDatabase db = dbHelper. getWritableDatabase (DBCipherHelper. DB_PWD); // obtain the readable database SQLiteDatabase db = dbHelper. getReadableDatabase (DBCipherHelper. DB_PWD );

 

The specific implementation is as follows:

 

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"; // statically reference private volatile static DBCipherManager mInstance; // DatabaseHelper private DBCiph ErHelper dbHelper; private DBCipherManager (Context context) {dbHelper = new DBCipherHelper (context. getApplicationContext ();}/*** obtain the 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) {// obtain the write database SQLiteDatabase db = dbHelper. getWritableDatabase (DBCipherHelper. DB_PWD); // generate the key value ContentValues cv = new ContentValues (); cv. put (DBCipherHelper. FIELD_NAME, name); // insert the database. insert (DBCipherHelper. TABLE_NAME, null, cv); // closes the database. close ();}/*** transaction batch insertion not enabled * @ param testCount */public v Oid insertDatasByNomarl (int testCount) {// obtain 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");} // closes the database. close ();}/*** test to enable transaction batch insert * @ Param testCount */public void insertDatasByTransaction (int testCount) {// obtain the write database SQLiteDatabase db = dbHelper. getWritableDatabase (DBCipherHelper. DB_PWD); db. beginTransaction (); // manually set start transaction try {// batch processing operation for (int I = 0; I <testCount; I ++) {// generate the key value 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 (); // sets whether the transaction is successfully processed. If this parameter is not set, the system automatically rolls back and does not submit.} catch (Exception e) {} finally {db. endTransaction (); // processing completed // closes the database. close () ;}/ *** delete data */public void deleteData (String name) {// generate the Condition Statement 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 the database. delete (DBCipherHelper. TABLE_NAME, whereBuffer. toString (), null); // closes the database. close ();}/*** delete all data */public void deleteDatas () {String SQL = "delete from" + DBCipherHelper. TABLE_NAME; execSQL (SQL);}/*** update data */public void updateData (String name) {// generate the Condition Statement StringBuffer whereBuffer = new StringBuffer (); w HereBuffer. append (DBCipherHelper. FIELD_NAME ). append ("= "). append ("'"). append (name ). append ("'"); // generate the key value ContentValues cv = new ContentValues (); cv. put (DBCipherHelper. FIELD_NAME, name + name); // obtain the write database SQLiteDatabase db = dbHelper. getWritableDatabase (DBCipherHelper. DB_PWD); // update the database. update (DBCipherHelper. TABLE_NAME, cv, whereBuffer. toString (), null); // closes the database. close ();}/*** specify the number of condition queries According to */public void queryDatas (String name) {// generate the Condition Statement StringBuffer whereBuffer = new StringBuffer (); whereBuffer. append (DBCipherHelper. FIELD_NAME ). append ("= "). append ("'"). append (name ). append ("'"); // specifies which columns of data to query String [] columns = {DBCipherHelper. FIELD_NAME}; // obtain the readable database SQLiteDatabase db = dbHelper. getReadableDatabase (DBCipherHelper. DB_PWD); // query database Cursor cursor = null; try {cursor = db. query (DBCi PherHelper. TABLE_NAME, columns, whereBuffer. toString (), 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 ();} // closes the database. close ();}/*** query all data */public void queryDatas () {// specify which columns of data to query String [] columns = {DBCipherHelper. FIELD_NAME}; // obtain the readable database SQLiteDatabase db = dbHelper. getReadableDatabase (DBCipherHelper. DB_PWD); // query database Cursor cursor = null; try {cursor = db. query (DBCipherHelper. TABLE_NAME, columns, nul L, null, null); // get the data cursor while (cursor. moveToNext () {int count = cursor. getColumnCount (); String columeName = cursor. getColumnName (0); // obtain the Table Structure Column name String name = cursor. getString (0); // obtain the table structure column data Log. e (TAG, "count =" + count + "columName =" + columeName + "name =" + name);} // close the cursor to prevent memory leakage if (cursor! = Null) {cursor. close () ;}} catch (SQLException e) {Log. e (TAG, "queryDatas" + e. toString ();} // closes the database. close ();}/*** Execute SQL statement */private void execSQL (String SQL) {// obtain the write database SQLiteDatabase db = dbHelper. getWritableDatabase (DBCipherHelper. DB_PWD); // directly execute the SQL statement db.exe cSQL (SQL); // or // close the database db. close ();}}
4.) How to call
// Clear the data DBCipherManager. getInstance (MainActivity. this ). deleteDatas (); // insert data for (int I = 0; I <10; I ++) {DBCipherManager. getInstance (MainActivity. this ). insertData (String. valueOf (I);} // deletes the data DBCipherManager. getInstance (MainActivity. this ). deleteData (String. valueOf (5); // update the data DBCipherManager. getInstance (MainActivity. this ). updateData (String. valueOf (3); // query data DBCipherManager. getInstance (MainActivity. this ). queryDatas ();
5.) transaction support is the same as that in traditional methods.
// Obtain the write database SQLiteDatabase db = dbHelper. getWritableDatabase (); db. beginTransaction (); // manually set start transaction try {// process batch operations here for (int I = 0; I <testCount; I ++) {// generate the key value ContentValues cv = new ContentValues (); cv. put (DBHelper. FIELD_NAME, String. valueOf (I); // insert operation db. insert (DBHelper. TABLE_NAME, null, cv);} db. setTransactionSuccessful (); // sets whether the transaction is successfully processed. If this parameter is not set, the system automatically rolls back and does not submit.} catch (Exception e) {} finally {db. endTransaction (); // processing completed // closes the database. close ();}

 

Summary:

SQLCipher usage summary ends here.

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.