SQLCipher Android (Data Migration from unencrypted DB to encrypted one...)


#1

I am trying to integrate SQLCipher in one of my application and I want to take care of the unencrypted DB of the users who have already installed my app, So what I have done is, created a method (Pasted below ) which migrates the old unencrypted DB to encrypted one for the first time app is updated with SQLCipher implementation.

public static void encrypt(Context ctxt, String dbName, String passphrase) throws IOException 
{
	File originalFile=ctxt.getDatabasePath(dbName);

	if (originalFile.exists()) 
	{
		File newFile = File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir());

		SQLiteDatabase db = SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),passphrase, null, SQLiteDatabase.OPEN_READWRITE);

		db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
             newFile.getAbsolutePath(), passphrase));

		db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
		db.rawExecSQL("DETACH DATABASE encrypted;");

		int version=db.getVersion();

		db.close();

		db=SQLiteDatabase.openDatabase(newFile.getAbsolutePath(),passphrase, null,SQLiteDatabase.OPEN_READWRITE);

		db.setVersion(version);
		db.close();

		originalFile.delete();
		newFile.renameTo(originalFile);
	}
}

but while trying to open database in 4th line of the above method, app crashes with the following error message, Please help…

01-12 05:51:16.568: I/Database(4160): sqlite returned: error code = 26, msg = file is encrypted or is not a database
01-12 05:51:16.568: E/Database(4160): CREATE TABLE android_metadata failed
01-12 05:51:16.588: E/Database(4160): Failed to setLocale() when constructing, closing the database
01-12 05:51:16.588: E/Database(4160): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database


#2

Is this the line that is failing? If so, what value is stored in passphrase when this is executed? It appears from its usage below that it is likely a non-empty string value. If the originalFile reference is to a plaintext SQLite database you would not want to provide a password when attempting to open a connection to the original database.


#3

Yes, this is the line that is failing and yes you right, a non-empty string value is stored in the passphrase when it is executed.

I tried “” in place of passphrase for opening originalFIle and it succeeded in exporting the DB file.

It was of great help. Thankyou vary much…


#4

Hi @Raj

We are glad to hear that worked for you, take care!


#5

Before encryption my DBHelper class looks like:

My DBHelper opens the unencrypted Db right now.
public DBHelper open() throws SQLException{
db = myDBHelper.getWritableDatabase("");
return this;
}

How do I make sure the app has the password to open the new encrypted db next time?


#6

Hello @bluefish

This posting appears to be a duplicate, I have replied to your inquiry here.