5

我正在尝试将未加密的 sqlite3 数据库的内容添加到使用 SQLCipher 的加密数据库中。我已经基于我正在尝试做的事情thisthis。然而,一些事情对我来说仍然不清楚。

  1. 顺带ATTACH DATABASE一提,加密数据库是否必须是类型.db?可以.sqlite匹配我的原始数据库吗?

  2. 所述加密数据库是否必须已经存在?如果是这样,它应该在应用程序中的什么位置?我是否必须提供文件的路径(文档目录等)?

  3. 我在哪里可以找到成功加密的数据库?它将被保存在哪里?

这是我的代码:

+ (void)encryptDB
{
    sqlite3 *unencrypted_DB;
    NSString *path_u = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                  stringByAppendingPathComponent:@"dict.sqlite"];

    if (sqlite3_open([path_u UTF8String], &unencrypted_DB) == SQLITE_OK) {
        NSLog(@"Database Opened");
        // Attach empty encrypted database to unencrypted database
        sqlite3_exec(unencrypted_DB, "ATTACH DATABASE 'dict_encrypted.sqlite' AS encrypted KEY '1234';", NULL, NULL, NULL);

        // Create new tables within encrypted database to match those in unencrypted database
        sqlite3_exec(unencrypted_DB, "CREATE TABLE encrypted.t1(A,B,C);", NULL, NULL, NULL);

        // Copy items from unencrypted database into encrypted database
        sqlite3_exec(unencrypted_DB, "INSERT INTO encrypted.t1 SELECT * FROM t1;", NULL, NULL, NULL);

        // Detach encrypted database
        sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, NULL);

        NSLog (@"End database copying");
        sqlite3_close(unencrypted_DB);
    }
    else {
        sqlite3_close(unencrypted_DB);
        NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
    }
}
4

3 回答 3

6

使用最新版本的 SQLCipher,我们有 sqlcipher_export() 函数,它可以使我们的代码更短,并且不连接到现有的数据库结构:

+ (void)encryptDB
{
    sqlite3 *unencrypted_DB;
    NSString *path_u = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                         stringByAppendingPathComponent:@"dict.sqlite"];

    if (sqlite3_open([path_u UTF8String], &unencrypted_DB) == SQLITE_OK) {
        NSLog(@"Database Opened");
        // Attach empty encrypted database to unencrypted database
        sqlite3_exec(unencrypted_DB, "ATTACH DATABASE 'dict_encrypted.sqlite' AS encrypted KEY '1234';", 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);

        NSLog (@"End database copying");
      sqlite3_close(unencrypted_DB);
    }
    else {
        sqlite3_close(unencrypted_DB);
        NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
    }
}
于 2012-04-03T16:35:58.580 回答
5
  1. 加密数据库是否必须是 .db 类型?-不,你可以使用任何你想要的扩展。
  2. 所述加密数据库是否必须已经存在?-不,数据库不需要已经存在。当您附加一个不存在的数据库时,它将创建一个新的
  3. 我是否必须提供文件的路径(文档目录等)?- 是的,您确实需要提供数据库的路径,否则将使用应用程序的当前工作目录。在 iOS 上,您通常应该提供文件名的完整路径,包括应用程序文档目录。
  4. 我在哪里可以找到成功加密的数据库?- 加密数据库将位于您告诉附加放置它的任何位置。根据 #3,如果您正在为 iOS 构建,请在文件名中包含文档目录的完整路径,然后加密的数据库将位于那里。
于 2012-01-20T15:43:51.770 回答
0

好吧,我从来没有做过ATTACH DATABASE,我使用的 SQLCiper 版本可能与你的不同,但是(对于我处理过的 SQLCipher 的实现),文件打开逻辑是标准 SQLite,并且行为方式相同就像没有 SQLCipher 一样。

因此,您不需要后缀 of.db或任何其他特定内容——您可以使用任何您想要的东西。

在您发布REKEY任何新数据库之前,它都是完全“正常的”,并且将以 SQLite 的“正常”方式创建/删除。

回复ATTACH DATABASE,我怀疑最好先创建数据库(和REKEY它),然后附加它。

于 2012-01-19T20:43:49.637 回答