0

I know that there are a few postings on this, but just want to make sure there is something that I am not missing / current.

Using sqlcipher, with an unencrypted database, want to encrypt it. Encrypting a new database is working fine.

Am trying the sqlcipher rekey with an existing database seems NOT to be working (Database remains unencrypted).

       [fmdb open];
       NSString *sel = @"SELECT count(*) FROM sqlite_master";            
       FMResultSet *fmr = [self executeQuery : fmdb : sel];

        if ( [fmr next] ) // unencrypted
        {
            NSLog(@"Encrypting");
            fmdb.key = @"";
            [fmdb rekey : @"somekey"];
        }

Otherwise will have to use one of the other PRAGMA methods, etc.

Does rekey only work with databases that are already encrypted?

This is using the FMDatabase Framework, but under the hood in the framework it is doing ...

    - (BOOL)rekey:(NSString*)key {
    #ifdef SQLITE_HAS_CODEC
    if (!key) {
        return NO;
    }

    int rc = sqlite3_rekey(db, [key UTF8String], (int)strlen([key UTF8String]));

    if (rc != SQLITE_OK) {
        NSLog(@"error on rekey: %d", rc);
        NSLog(@"%@", [self lastErrorMessage]);
    }

    return (rc == SQLITE_OK);
    #else
        return NO;
    #endif
   }

It does run though the sqlite3_rekey, no errors, but database does not get encrypted.

ort11
  • 3,359
  • 4
  • 36
  • 69
  • PRAGMA REKEY is what you use. You then, of course, need to do PRAGMA KEY (*after* the REKEY) to set the new key value. (I don't know what your fmdb functions translate as. Presumably `rekey` translates to PRAGMA REKEY. There should also be a `key` or `setkey` function.) – Hot Licks Apr 11 '12 at 14:31
  • Do note that SQLite requires the DB to be in a certain relatively "pure" state to be rekeyed. There shouldn't be any open queries, etc, and it may be that you have to close and reopen before doing the REKEY -- I forget the details.) – Hot Licks Apr 11 '12 at 14:35
  • If you do PRAGMA_REKEY and the DB does not become encrypted either you specified a blank/empty key or SQLCipher isn't installed. Once again, I don't know what the `rekey` function does. – Hot Licks Apr 11 '12 at 22:44
  • I have exactly the same problem today (FMDB, sqlcipher, iOS). Rekey feature does nothing... Did you find a solution ? – alex.bour Apr 12 '12 at 08:40

2 Answers2

4

All of the previous comments on this question are incorrect. You cannot use rekey to encrypt a plaintext database. Rekey is only to be used to change the encryption key on an encrypted database.

The correct way to encrypt a plaintext database is attach and export - see examples here http://sqlcipher.net/sqlcipher-api/#sqlcipher_export

Stephen Lombardo
  • 1,503
  • 8
  • 7
  • Well, now I have done this and the database encrypts fine with the attache , but only once. When I try to open the database again with the same password, it says it is encrypted and will not open. – ort11 Apr 12 '12 at 21:43
  • did you close the original database, reopen the new encrypted database, and set the key again? – Stephen Lombardo Apr 16 '12 at 14:18
0

The trick was that when the database is used to check for encryption (next time opening app) when it is already encrypted, but do not use a key to do a select, this will fail, but then the database will HAVE to be closed and reopened again with the key.

ort11
  • 3,359
  • 4
  • 36
  • 69