How to encrypt/decrypt in SQLCipher

Monty picture Monty · Jan 29, 2013 · Viewed 10.1k times · Source

I am struggling with How to encrypt/decrypt DB with SQLCipher.

In my this code from where i should start. and how to start.

Please Edit this code if possible.

I followed this link but not getting how to do that. http://sqlcipher.net/sqlcipher-api/#key

My DB file:-

import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;
import android.content.Context;
import android.util.Log;

public class DatabaseClass extends SQLiteOpenHelper 
{
    /**
     * Constants 
     */
    public final static String DATABASE_NAME ="mycipherdatabase.db";
    public final static String NAME ="name";
    public final static String ADDRESS ="address";
    public final static String CITY ="city";

    public static String pass = "1234";
    public DatabaseClass(Context context) {
        super(context, DATABASE_NAME, null, 1);
    }

    /**
     * called once
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL( "CREATE TABLE mylistdata(_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, address TEXT,city TEXT);");

        Log.v("inside", "oncreate");
    }

    /**
     * called when we upgrade(change)the version number of database
     * onCreate also called after changing the version
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP Table mylistdata");
        onCreate(db);
    }
}

OtherActivity Using this DB:-

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        SQLiteDatabase.loadLibs(this);
        File file = getDatabasePath(DatabaseClass.DATABASE_NAME);
        file.mkdir();
        file.delete();
        sqldb = SQLiteDatabase.openOrCreateDatabase(file,key, null);
        db = new DatabaseClass(this);

        etname = (EditText)findViewById(R.id.name);
        etadd = (EditText)findViewById(R.id.add);
        etcity = (EditText)findViewById(R.id.city);
        result = (ListView)findViewById(R.id.mylist);
    }

    /**
     *insert data in to database 
     */
    public void saveData(View v) {
        ContentValues insertData = new ContentValues();
        insertData.put(DatabaseClass.NAME, etname.getText().toString());
        insertData.put(DatabaseClass.ADDRESS, etadd.getText().toString());
        insertData.put(DatabaseClass.CITY, etcity.getText().toString());

        db.getWritableDatabase(key).insert("mylistdata", DatabaseClass.NAME , insertData);
        db.close();

        resetEditText();
        Toast.makeText(this,"Data saved", Toast.LENGTH_SHORT).show();
    }

Answer

Hossein Shahdoost picture Hossein Shahdoost · Apr 15, 2013

Well, There are so many problems with the code, that I think you must have a better look at SQLite structure in android, technically, Android SQLite and SQLCipher look totally the same (except for the password). so if you write an standard SQLite application, it can be changed to SQLCipher easily,

I suggest you read this fine article about SQLite in android,

http://www.vogella.com/articles/AndroidSQLite/article.html

Tip: There is no need to call openOrCreateDatabase when you are using SQLiteOpenHelper, calling getWritableDatabase would do the job, also you must be having a SQLiteDatabase object which is taken from getWritableDatabase method, calling getWritableDatabase for every time you want to insert a record is not right.

these parts would be removed,

     // in onCreate method
     File file = getDatabasePath(DatabaseClass.DATABASE_NAME);
     file.mkdir();
     file.delete();
     sqldb = SQLiteDatabase.openOrCreateDatabase(file,key, null);
     db = new DatabaseClass(this);

     // in saveData method
      db.getWritableDatabase(key).insert("mylistdata", DatabaseClass.NAME ,               insertData);

Instead you must do something like this

     // in onCreate method
     try{
        sqldb = new DatabaseClass(this).getWritableDatabase(key);
     }catch(Throwable e){
        // error occurred
     }

     // in insert action
     try{
        sqldb.insert("tablename", null, contentValues);
     }catch(Throwable e){
        // error occurred
     }

This way you can also see if an error occurred, Remember, not to use Exception class on the catch phrase, only Throwable!

Also, I would not suggest to close the connection on every insert action, It's better to be taken care of in higher levels