问题
I have previously asked this question and have not got any appropriate answer.
I have an app published in the Play Store which makes heavy use of SQLite database.
Now I need to secure the database using SQLCipher. Here are some problems I am facing.
1) How can I seamlessly integrate SQLCipher with my existing unencrypted database, so that my app works as it works normally but now the databases are encrypted?
(I would like a short tutorial on this)
2) How should I check if the database is unencrypted and then how can I encrypt it? Should I do this only once? What should be the best practice?
(The possible duplicate doesn't answer this)
3) When I encrypt my existing unencrypted database, do SQLCipher create a new database? If yes, how should I be managing this new one? And what about my old database which is unencrypted? Does it still stay there?
(This explanation is also not provided in the duplicate question)
回答1:
How can I seamlessly integrate SQLCipher with my existing unencrypted database, so that my app works as it works normally but now the databases are encrypted?
You don't. Among other things, you have to adjust your UI to ask the user for a passphrase, and ensure that you can ask for that passphrase as needed (e.g., user resumes a task from some "inner" activity, not just when the user runs your app via a launcher icon).
I would like a short tutorial on this
First, that is not how Stack Overflow works.
Second, decent coverage of SQLCipher for Android takes much more than can fit in a single Stack Overflow answer. I have an 18-page chapter on the subject in my book, for example. This answer is already longer than the vast majority of Android questions, and I would not blame people for closing this question as being too broad.
How should I check if the database is unencrypted
Try opening it using the SQLCipher for Android classes with ""
as the passphrase. If it opens successfully, the database is unencrypted. If that fails, either the database is corrupt or encrypted, and without the proper passphrase, you cannot tell the difference.
how can I encrypt it?
The basic approach is:
Open the unencrypted database
Use the
ATTACH
SQL statement to attach an empty file to serve as the new encrypted database, supplying your desired passphrase, and naming the attached databaseencrypted
within your database sessionRun the
SELECT sqlcipher_export('encrypted')
in the open (unencrypted) database, which will export the data from the unencrypted database into the encrypted one (with the exception of the database schema version, which is handled in later steps)Call
getVersion()
on the open (unencrypted) database and hold onto that value for a bitClose the unencrypted database
Open the encrypted database, using your passphrase
Call
setVersion()
on the encrypted database, supplying the value you cached fromgetVersion()
of the unencrypted databaseClose the encrypted database
If desired, delete the unencrypted database and rename the encrypted one to the name of the now-deleted unencrypted one, so that your conversion appears to happen in place
This utility method implements the above approach:
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(),
"", 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);
}
}
In the interests of full disclosure, I have not tried this in a while, and so there may need to be some tweaks.
Should I do this only once?
Only you can answer that, as nobody here is going to know much about your app.
When I encrypt my existing unencrypted database, do SQLCipher create a new database?
Yes.
If yes, how should I be managing this new one?
Only you can answer that, as nobody here is going to know much about your app.
And what about my old database which is unencrypted? Does it still stay there?
Yes, though you are welcome to delete it if and when you are done with it.
来源:https://stackoverflow.com/questions/29860873/using-sqlcipher-with-android