Detailed information on the Android data storage Sqlcipher database encryption _android

Source: Internet
Author: User
Tags bulk insert readable sqlite sqlite database stringbuffer


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.


Related Article

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.