Tuesday, September 17, 2013

SQLCipher in android

Hi guys,

After a long time, am posting one more topic. This is related SQLCipher in android.
My requirement is to secure my database if the application is not running. So, I will be encrypting the db, while it goes to background ie. onStop. And decrypting it in the onStart method. For encryption/decryption, I have used SQLCipher. You guys can go through this here, http://sqlcipher.net/sqlcipher-for-android/.

In my application, I have one database with one table.

Encryption in onStop is as follows,

 @Override
 protected void onStop() {
  try {
   ConvertNormalToSQLCipheredDB(this,
   PhoneNumbersDatabase.DATABASE_NAME, "encrypt.db", "test123");
  } catch (IOException e) {
   e.printStackTrace();
   Log.d("<<<< mydebug >>>>>", " >>>>>> : " + e.toString());
  }
  super.onStop();
 }

 private static void ConvertNormalToSQLCipheredDB(Context context,
 String startingFileName, String endingFileName, String filePassword)
 throws IOException {
  File mStartingFile = context.getDatabasePath(startingFileName);
  if (!mStartingFile.exists()) {
   return;
  }
  File mEndingFile = context.getDatabasePath(endingFileName);
  mEndingFile.delete();
  SQLiteDatabase database = null;
  try {
   database = SQLiteDatabase.openOrCreateDatabase(MainApp.mainDBPath,
   "", null);
   database.rawExecSQL(String.format(
   "ATTACH DATABASE '%s' AS encrypted KEY '%s'",
   mEndingFile.getAbsolutePath(), filePassword));
   database.rawExecSQL("select sqlcipher_export('encrypted')");
   database.rawExecSQL("DETACH DATABASE encrypted");
   database.close();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (database.isOpen())
    database.close();
   mStartingFile.delete();
  }
 }
}
and decrypting it in onStart method is as follows,

private void decryptDatabase() {
  File unencryptedFile = getDatabasePath(PhoneNumbersDatabase.DATABASE_NAME);
  unencryptedFile.delete();
  File databaseFile = getDatabasePath("encrypt.db");
  SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {
   public void preKey(SQLiteDatabase sqLiteDatabase) {
    sqLiteDatabase
      .rawExecSQL("PRAGMA cipher_default_use_hmac = off;");
   }

   public void postKey(SQLiteDatabase sqLiteDatabase) {
   }
  };
  SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
    databaseFile, "test123", null, hook);
  if (database.isOpen()) {
   database.rawExecSQL(String.format(
     "ATTACH DATABASE '%s' as plaintext KEY '';",
     unencryptedFile.getAbsolutePath()));
   database.rawExecSQL("SELECT sqlcipher_export('plaintext');");
   database.rawExecSQL("DETACH DATABASE plaintext;");
   android.database.sqlite.SQLiteDatabase sqlDB = android.database.sqlite.SQLiteDatabase
     .openOrCreateDatabase(unencryptedFile, null);
   sqlDB.close();
   database.close();
  }

  databaseFile.delete();
 }

 @Override
 protected void onStart() {
  super.onStart();
  decryptDatabase();
 }