Migrating SQLCipher ver. 2.x DB to ver. 3.x using by FMDB

542 views Asked by At

I saw the following page and I understand I should execute the query "PRAGMA cipher_migrate".

https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate

But I have no idea how to use it on FMDatabase. The following code did not work... (Seems like not only the timing of the execution is wrong...)

I'd like you to let me know your workaround if you have tried migrating SQLCipher ver.2.x DB to ver.3.x using by FMDatabase.

- (FMDatabase *)openDB {

    NSArray *directories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *directory = [directories objectAtIndex:0];
    NSString *path = [directory stringByAppendingPathComponent:dbFileName];
    FMDatabase *dataBase = [FMDatabase databaseWithPath:path];

    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    int version = [userDefault integerForKey:DATABASE_TABLE_VERSION];

    if(version==1){

        if(![dataBase openWithFlags:SQLITE_OPEN_READWRITE]){
            @throw [NSException exceptionWithName:@"DBException"
                                           reason:@"openWithFlags"
                                         userInfo:nil];
        }

        if(![dataBase setKey:SQLCIPHER_KEY]){
            @throw [NSException exceptionWithName:@"DBException"
                                           reason:@"setKey"
                                         userInfo:nil];
        }

        if(![dataBase executeStatements:@"PRAGMA kdf_iter = 4000"]){
            @throw [NSException exceptionWithName:@"DBException"
                                           reason:@"executeStatements:kdf_iter"
                                         userInfo:nil];
        }

        [userDefault setInteger:2 forKey:DATABASE_TABLE_VERSION];
        [userDefault synchronize];

        return dataBase;
    }

    if(![dataBase open]){
        @throw [NSException exceptionWithName:@"DBException"
                                       reason:@"open"
                                     userInfo:nil];
    }

    if(![dataBase setKey:SQLCIPHER_KEY]){
        @throw [NSException exceptionWithName:@"DBException"
                                       reason:@"setKey"
                                     userInfo:nil];
    }

    return dataBase;
}

- (NSMutableArray *)selectUser{

    FMDatabase *dataBase = [self openDB];
    NSString *sql = @"select * from t_user";
    FMResultSet *resultSet = [dataBase executeQuery:sql];

    NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects: nil];

    while ([resultSet next]){
        [mutableArray addObject:[resultSet resultDictionary]];
    }

    [resultSet close];
    [dataBase close];
    return mutableArray;
}
1

There are 1 answers

1
malex On

I think you need to set cipher key right after connection and before any execution.

Also if you use

PRAGMA kdf_iter = 4000

you don't need to use

PRAGMA cipher_migrate