Question

I've just implemented SQLCipher in my app to encrypt one fairly simple database. I followed all of the setup instructions carefully on this tutorial and the project is building and the app is running successfully. However, when I use their sample code to encrypt my database, my password is somehow incorrect and I am now unable to open my database. Here is the code:

NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                      stringByAppendingPathComponent: @"dict.sqlite"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
        const char* key = [@"BIGSecret" UTF8String];
        sqlite3_key(database, key, strlen(key));
        if (sqlite3_exec(database, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
            // password is correct, or, database has been initialized
            NSLog(@"Correct Password :)");
        } 
        else {
            // incorrect password!
            NSLog(@"Incorrect Password :(");
        }
    }
    else {
        sqlite3_close(database);
        NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
    }
}

sqlite3 *database; is declared in my interface. My app is crashing on this line:

if (sqlite3_prepare_v2(database, sql, -1, &init_statement, NULL) != SQLITE_OK) {
    NSAssert1(NO, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}

Everything worked just fine without the encryption, so there is no issue with the rest of my code. The console prints "Incorrect Password :(" before the crash. The crash log is: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error: failed to prepare statement with message 'file is encrypted or is not a database'.' There is clearly an issue with the password. Any help?

Thanks.

Was it helpful?

Solution

The most likely problem is that you are trying to set a key on an existing database that is not already encrypted, dict.sqlite. The sqlite3_key function does not encrypt an existing database. If you want to encrypt an existing database you'd either need to ATTACH a new encrypted database and move data between the two, as described here:

http://zetetic.net/blog/2009/12/29/how-to-encrypt-a-plaintext-sqlite-database-to-use-sqlcipher/

Or, using the SQLCipher 2 you can use sqlcipher_export which provides an easy way to move data between databases.:

http://groups.google.com/group/sqlcipher/msg/76d5b03426419761

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top