About Sqlite,sqlcipher and Fmdb
SQLite is a lightweight, cross-platform, open-source database engine that has the advantage of read-write efficiency, total consumption, latency, and overall simplicity, making it the best solution for mobile platform databases (such as iOS, Android). However, the free version of SQLite has a fatal disadvantage: encryption is not supported. This results in the data stored in SQLite can be seen by anyone using any text editor.
If we want to encrypt our database, the solution is to use another open source encrypted database Sqlcipher,sqlcipher using 256-bit AES encryption, because it is based on the free version of SQLite, the main encryption interface and SQLite are the same, Of course, it also adds some of its own interfaces, such as setting a secret key to a database when creating and opening a database.
Fmdb is an open source class library, it is a good package for SQLite database operation, but also increased support for sqlcipher, that is, we do not directly with Sqlcihper can also complete the decryption operation, and Fmdb in the operation of SQLite is much more convenient. Today's app development, if it involves database operations, Fmdb is basically the first choice.
The following is a brief introduction and code implementation of an app that ignores database privacy at an early stage and requires that the database be upgraded for encryption in the medium term. If the reader does not use Fmdb, the direct use of sqlite, that this article also has a certain reference, only about Sqlcipher configuration, and is not introduced, because although FDMB encryption is also used Sqlcipher, but does not need to be configured.
Fmdb version with encryption capability
The encrypted Fmdb is actually a branch, that is, if you need to replace Fmdb. The installation of this branch on GitHub only provides the Cocospod installation method.
Fmdb address on GitHub: Https://github.com/ccgus/fmdb
For example, if you used to write the following
Pod ' FMDB '
If you want to switch to a cryptographic function, change to
Pod ' Fmdb/sqlcipher '
Upgrade Database Code Implementation
After we get the right version, we need to do some processing in the code to get the old database to upgrade. The upgrade here includes two points:
1 is what we said earlier, encrypt the database.
2 Migrate the tables and data from the old database to the new database.
The use of Sqlcipher and SQLite is not much difference, it is worth noting that every time when [DP Open] is successful, you need to give the database password, that is [db Setkey:db_secretkey], Db_secretkey is one of our custom macros. After that, we can read out the contents of the database.
Fmdatabase *_db = [fmdatabase databasewithpath:[cachepath stringbyappendingstring:dbfilename]];if (![ _DB Open]) { _db = nil; return;} else{ [_db setkey:db_secretkey];}
Then we need to determine if the database needs to be upgraded, when using Sqlchipher to open the source database generated with SQLite, [DP Goodconnection] is no, even if the above [DB Open] operation is yes.
if (![ _db Goodconnection]) {//invalid connection [self upgradedatabase:dbpath];}
Next, is the data migration, path is our source database path, assuming our source database name is dbname, Changedatabasepath is about to change our database A to dbname.tmp, next is to create a new database B, because a in the previous has been renamed to Dbname.tmp, and B will be the future we want to replace a database, so the B name here is dbname. Finally, the DBNAME.TMP data is copied to the dbname, and then delete the dbname.tmp, to this, our database upgrade is complete.
-(void) Upgradedatabase: (NSString *) path{nsstring *tmppath = [self changedatabasepath:path]; if (tmppath) {const char* SQLQ = [[NSString stringwithformat:@ "ATTACH DATABASE '%@ ' as encrypted KEY '%@ ';", path,db_ Secretkey] utf8string]; Sqlite3 *unencrypted_db; if (Sqlite3_open ([Tmppath utf8string], &unencrypted_db) = = SQLITE_OK) {//Attach empty Encrypt Ed database to unencrypted database sqlite3_exec (unencrypted_db, SQLQ, NULL, NULL, and NULL); Export Database Sqlite3_exec (unencrypted_db, "Select Sqlcipher_export (' encrypted ');", NULL, NULL, NULL); Detach Encrypted Database Sqlite3_exec (unencrypted_db, "Detach database encrypted;", NULL, NULL, NULL); Sqlite3_close (unencrypted_db); Delete TMP database [self removedatabasepath:tmppath]; } else {Sqlite3_close (unencrypTED_DB); NSAssert1 (NO, @ "Failed to open database with message '%s '.", Sqlite3_errmsg (unencrypted_db)); } }}
-(NSString *) Changedatabasepath: (NSString *) path{ nserror * err = NULL; NSFILEMANAGER * fm = [[Nsfilemanager alloc] init]; NSString *tmppath = [NSString stringwithformat:@ "%@.tmp", path]; BOOL result = [FM moveitematpath:path topath:tmppath error:&err]; if (!result) { NSLog (@ "Error:%@", err); return nil; } else{ return tmppath;} }
After the above steps, we know that although Sqlchipher is based on SQLite, but in the end is not the same, we can not directly upgrade the SQLite database to Sqlchipher, only with Sqlchipher to create a new database, and then re-write data.
The above code is just an example, the data storage model for each app is not the same, here I can not give a template. While the code is not necessarily applicable, the order in which the code is executed is positive when the database is upgraded: Opening the database open, setting key Setkey, view connection goodconnection new database and migrating data upgrade.
IOS uses Fmdb sqlcipher to encrypt the database