iOS上的SQLite + SQLCipher + FMDatabase

时间:2012-04-11 13:10:23

标签: ios sqlite sqlcipher

我目前正在iOS应用中使用FMDatabase,我对它非常满意。 我打算用SQLCipher加密sqlite数据库。

以下是我的问题:

1)FMDatabase和SQLCipher兼容吗?我想我只需要在FMDatabase中添加一个名为openEncrypted的新方法......并为SQLCipher完成工作。我希望所有FMDatabase方法都能正常工作。

2)实际上,我的应用程序中有2个数据库。然后我在我的应用程序中执行ATTACH DATABASE加入它们。我想加密两个中的一个。它会工作还是我需要加密2个数据库? (一个是关键,另一个不是)

3)如果我加密这些文件,我真的不明白我将要向Apple(文件)提供什么。

谢谢!

3 个答案:

答案 0 :(得分:2)

对于那些寻找如何实现这一目标的简单教程的人,我能够创建一个:http://www.guilmo.com/fmdb-with-sqlcipher-tutorial/

但最重要的部分是,打开现有数据库并附加新的加密数据库。然后在FMDB连接中设置密钥。

SQLCipher - 加密数据库

// Import sqlite3.h in your AppDelegate
#import <sqlite3.h>

// Set the new encrypted database path to be in the Documents Folder
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
NSString *ecDB = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"];

// SQL Query. NOTE THAT DATABASE IS THE FULL PATH NOT ONLY THE NAME
const char* sqlQ = [[NSString stringWithFormat:@"ATTACH DATABASE '%@' AS encrypted KEY 'secretKey';",ecDB] UTF8String];

sqlite3 *unencrypted_DB;    
if (sqlite3_open([self.databasePath UTF8String], &unencrypted_DB) == SQLITE_OK) {

    // Attach empty encrypted database to unencrypted database
    sqlite3_exec(unencrypted_DB, sqlQ, NULL, NULL, 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);
}
else {
    sqlite3_close(unencrypted_DB);
    NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
}

self.databasePath = [documentDir stringByAppendingPathComponent:@"encrypted.sqlite"];

请注意,我们在SQL Query,DATABASE和KEY中设置了2个参数。 DATABASE应该是要创建的加密数据库的完整路径,在本例中为字符串ecDB,KEY参数是用于加密数据库的密钥,因此请选择强大的

现在在你的FMDB功能上,每次打开数据库后都要调用 [db setKey:@“strongKey”]

// FMDatabase Example
FMDatabase *db = [FMDatabase databaseWithPath:[self getDatabasePath]];
[db open];
[db setKey:@"secretKey"];


// FMDatabaseQueue Exmple
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self getDatabasePath]];

[queue inDatabase:^(FMDatabase *db) {
    [db setKey:@"secretKey"];
    ...
}];

如果您有任何疑问,请与我联系!

答案 1 :(得分:1)

  1. 是的,你仍然需要在SQLCipher中编译,但你可以使用FMDB。 FMDB还提供了为数据库设置加密密钥的功能
  2. 您可以将未加密的数据库附加到加密数据库(请参阅http://sqlcipher.net/sqlcipher-api/#attach
  3. 您通常需要对DOC进行加密注册,然后自我归类为大众市场http://www.bis.doc.gov/encryption/question4.htm

答案 2 :(得分:0)

您好我正在使用swift,以下是我遵循的代码。但我有一个问题,我可以用SQLiteBrowser打开encrypted.sqlite文件,我在这里错了。

 var db: COpaquePointer = nil;
        let databasePath = FileUtils.getPath("data.db")
        var ecDB = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0].stringByAppendingPathComponent("encrypted.sqlite")
  let result = String.fromCString("ATTACH DATABASE \(ecDB) AS encrypted KEY TaP")
if (sqlite3_open(databasePath, &db) == SQLITE_OK) {
 sqlite3_exec(db, result!, nil, nil, nil);
 sqlite3_exec(db, "SELECT sqlcipher_export('encrypted');", nil, nil, nil);
 sqlite3_exec(db, "DETACH DATABASE encrypted;", nil, nil, nil);
sqlite3_close(db);
        }
        else {
            sqlite3_close(db);
            sqlite3_errmsg(db);
        }