0

I am using SQLCipher to encrypt SQLite databases. I seem to run into trouble to ATTACH an encrypted database with a custom cipher_page_size (different from the default value of 1024).

Here is my code

- (void) database:(sqlite3*) database execute:(NSString*) sql {
    if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
        NSLog(@"\"%@\" successfully executed", sql);
    } else {
        NSLog(@"Could not execute \"%@\" (%s)", sql, sqlite3_errmsg(database));
    }
}

- (void)test {

    sqlite3 *database1;
    sqlite3 *database2;

    NSString *path1 = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
                        stringByAppendingPathComponent:@"database1.sqlite"];
    NSString *path2 = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
                        stringByAppendingPathComponent:@"database2.sqlite"];

    if (sqlite3_open([path1 UTF8String], &database1) == SQLITE_OK) {
        NSLog(@"database1 opened successfully");
        [self database:database1 execute:@"PRAGMA key = 'password1';"];
        //[self database:database1 execute:@"PRAGMA cipher_page_size = 2048;"];
        [self database:database1 execute:@"CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, name TEXT);"];
        [self database:database1 execute:@"INSERT INTO table1 (name) VALUES ('bob');"];
        sqlite3_close(database1);
    } else {
        sqlite3_close(database1);
        NSLog(@"Failed to open database1 with message '%s'.", sqlite3_errmsg(database1));
    }

    if (sqlite3_open([path2 UTF8String], &database2) == SQLITE_OK) {
        NSLog(@"database2 opened successfully");
        [self database:database2 execute:@"PRAGMA key = 'password2';"];
        //[self database:database2 execute:@"PRAGMA cipher_page_size = 2048;"];
        [self database:database2 execute:@"CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY, name TEXT);"];
        [self database:database2 execute:@"INSERT INTO table2 (name) VALUES ('john');"];

        [self database:database2 execute:[NSString stringWithFormat:@"ATTACH DATABASE '%@' AS database1 KEY 'password1';", path1]];
        [self database:database2 execute:@"DETACH DATABASE database1;"];

        sqlite3_close(database2);
    } else {
        sqlite3_close(database2);
        NSLog(@"Failed to open database2 with message '%s'.", sqlite3_errmsg(database2));
    }
}

When the lines about changing the cipher_page_size are commented the code works as expected. When they are commented out I get error SQLITE_NOTADB (database is encrypted or not a database file).

quentinadam
  • 3,058
  • 2
  • 27
  • 42

1 Answers1

1

You should explicitly set the page size for the attached database immediately after you attach it, i.e.:

ATTACH DATABASE 'db1.db' AS database1 KEY 'password1';
PRAGMA database1.cipher_page_size = 2048;
Stephen Lombardo
  • 1,503
  • 8
  • 7
  • Unfortunately that does not work as the error arises on the ATTACH statement itself. – quentinadam Jan 22 '13 at 23:22
  • This is a bug, the core library is using the default page size during the attach. I've logged it and we'll take a closer look into it. For the time being, do you have the option to use the default page size of 1024? – Stephen Lombardo Jan 29 '13 at 14:45
  • Thanks. Yes I got around the problem by changing slightly my data structure and now do not need to ATTACH. Thanks for submitting the bug. – quentinadam Jan 29 '13 at 17:24
  • @StephenLombardo what is the difference between cipher_page_size added in SQLCipher and the original page_size declared in SQLite3? If I changed the SQLITE_DEFAULT_PAGE_SIZE declared in SQLite source code, which I think it is equivalent to "PRAGMA page_size = xxx", does it have nothing to do with cipher_page_size used by SQLCipher? – gzh Feb 15 '22 at 14:03
  • 1
    @gzh the SQLITE_DEFAULT_PAGE_SIZE is only used for non-encrypted databases. SQLCipher uses a separate page size setting for encrypted databases, which is 4096 by default in SQLCipher 4. – Stephen Lombardo Feb 15 '22 at 19:55
  • @StephenLombardo, Thanks. – gzh Feb 15 '22 at 23:00