OGeek|极客世界-中国程序员成长平台

标题: iOS sqlcipher fmdb “File is encrypted or is not a database” [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 11:31
标题: iOS sqlcipher fmdb “File is encrypted or is not a database”

这个 tutorial与以下代码配合使用即可。

pod 'FMDB/SQLCipher'

...

- (BOOL)applicationUIApplication *)application didFinishLaunchingWithOptionsNSDictionary *)launchOptions
{
...

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir = [documentPaths objectAtIndex:0];
    self.databasePath = [documentDir stringByAppendingPathComponent"gameDefault.sqlite"];

    [self createAndCheckDatabase];

...
}

...

-(void) createAndCheckDatabase
{
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:self.databasePath];

    if(success) return; // If file exists, dont do anything

    // if file does not exist, make a copy of the one in the Resources folder
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent"gameDefault.sqlite"]; // File path

    [fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil]; // Make a copy of the file in the Documents folder

    // 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"];
}

...

[db setKey"secretKey"]

...

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

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

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

...

当我在其他项目中使用相同的代码时,它可以很好地加密现有的 sqlite 数据库。 但是当我尝试通过 sql select 查询访问表时,我收到错误消息“文件已加密或不是数据库”。 不过,教程应用程序没有问题,我可以更新/插入/删除/选择那里的记录。有什么线索吗?



Best Answer-推荐答案


我已经解决了。如前所述,相同的代码行为不同,因此设置可能有问题。在我的应用程序中,我添加了 SQLCipher 和 FMDB,如下所示:

pod 'SQLCipher', '~> 3.1'
pod 'FMDB', '~> 2.5'

在该教程中,它们被添加为

pod 'FMDB/SQLCipher'

不过,此 pod 命令根据此处显示的终端输出下载相同版本的 SQLCipher 和 FMDB

Updating local specs repositories
Analyzing dependencies
Downloading dependencies
Installing FMDB (2.5)
Installing SQLCipher (3.1.0)
Generating Pods project
Integrating client project

所以,我像教程中的那样更改了 pod 命令,并且该错误已修复。不过,我不知道这些命令有何不同。

关于iOS sqlcipher fmdb “File is encrypted or is not a database”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32039702/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4