3

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();
    }
Monty
  • 3,205
  • 8
  • 36
  • 61

3 Answers3

4

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

Hossein Shahdoost
  • 1,692
  • 18
  • 32
  • I'm not sure why you are recommending to catch Throwable rather than Exception. The javadocs for the other Throwable subclass (ie Error) say that it is not reasonable to catch Errors: http://docs.oracle.com/javase/6/docs/api/java/lang/Error.html – James Baxter Oct 07 '13 at 20:01
  • 2
    We have two kinds of Throwables, Exceptions and Errors. Sometimes SQLCipher returns Error (if any library is missing) not Exception. In order to catch that you should use Throwable on the catch statement. Even though it should be handled in multiple levels but you should always remember to write your sqlcipher commands inside a Throwable catch in order to avoid your app from crashing, http://stackoverflow.com/questions/2274102/difference-between-using-throwable-and-exception-in-a-try-catch – Hossein Shahdoost Oct 30 '13 at 09:52
1

Try using SQLiteDatabase.openOrCreateDatabase as described here: http://sqlcipher.net/sqlcipher-for-android/

Stephen Lombardo
  • 1,503
  • 8
  • 7
  • what file.mkdir and file.delete doing there ..they are mandatory to use..i edit my code please review it .i am doing right now or not. – Monty Jan 30 '13 at 04:43
0

This may be a good place to start, https://guardianproject.info/code/sqlcipher/

And more from the Android Docs, http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onConfigure(android.database.sqlite.SQLiteDatabase)

The key takeaways for me were add the sqlcipher jar to your android deps, and make sure you set the secret keys/passphrase PRAGMA stmts.

Sean McCully
  • 1,122
  • 3
  • 12
  • 21
  • Thanks for reply sean..i think , i am using these things you posted...i am passing a key in getWritableDatabase(pass)...is it encryption. – Monty Jan 29 '13 at 12:42
  • I don't see you using the onConfigure method and setting the Pragmas – Sean McCully Jan 29 '13 at 12:46
  • ok sean .your means inside onConfing().i need to do db.rawQuery("PRAGMA key "+some key+";"); ..am i right – Monty Jan 29 '13 at 12:50
  • Oh I don't know, I am just inferring from the docs, and what I know. I have not done this specifically. But yes you need to do something along those lines – Sean McCully Jan 29 '13 at 13:25
  • Sorry to revive this but, @Unknown have you figured out to execute the `PRAGMA key` command yet? Thanks I also need it. – Razgriz Sep 13 '13 at 11:57