代码之家  ›  专栏  ›  技术社区  ›  zeeawan

iOS sqlcipher fmdb文件已加密或不是数据库

  •  2
  • zeeawan  · 技术社区  · 9 年前

    tutorial 使用以下代码即可正常工作。

    pod 'FMDB/SQLCipher'
    

    ...

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)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查询访问表时,我得到了错误,“文件已加密或不是数据库”。 不过,教程应用程序没有问题,我可以在那里更新/插入/删除/选择记录。有线索吗?

    2 回复  |  直到 9 年前
        1
  •  2
  •   zeeawan    9 年前

    我已经修好了。如上所述,同一代码的作用不同,因此设置可能有问题。在我的应用程序中,我添加了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命令,错误被修复了。不过,我不知道这些命令有何不同。

        2
  •  2
  •   Uday Patel    5 年前

    我已经修好了。我认为FMDB&SQLCipher。我已经使用下面的链接解决了这个问题。现在,我的数据库文件使用SQLCipher和FMDB成功加密……:-D

    How to Use FMDB With SQLCipher?