Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attaching Encrypted Database to Unencrypted Database Using SQLCipher

I'm trying to add the contents of an unencrypted sqlite3 database to an encrypted one using SQLCipher. I've based what I am trying to do off of this and this. A few things however remain unclear to me.

  1. In line ATTACH DATABASE, does the encrypted database have to be of type .db? Can it be .sqlite to match my original database?

  2. Does said encrypted database have to already exist? If so, where should it be in the app? Do I have to provide a path to the file (documents directory, etc)?

  3. Where can I find the successfully encrypted database? Where will it be saved?

Here is my code:

+ (void)encryptDB
{
    sqlite3 *unencrypted_DB;
    NSString *path_u = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                  stringByAppendingPathComponent:@"dict.sqlite"];

    if (sqlite3_open([path_u UTF8String], &unencrypted_DB) == SQLITE_OK) {
        NSLog(@"Database Opened");
        // Attach empty encrypted database to unencrypted database
        sqlite3_exec(unencrypted_DB, "ATTACH DATABASE 'dict_encrypted.sqlite' AS encrypted KEY '1234';", NULL, NULL, NULL);

        // Create new tables within encrypted database to match those in unencrypted database
        sqlite3_exec(unencrypted_DB, "CREATE TABLE encrypted.t1(A,B,C);", NULL, NULL, NULL);

        // Copy items from unencrypted database into encrypted database
        sqlite3_exec(unencrypted_DB, "INSERT INTO encrypted.t1 SELECT * FROM t1;", NULL, NULL, NULL);

        // Detach encrypted database
        sqlite3_exec(unencrypted_DB, "DETACH DATABASE encrypted;", NULL, NULL, NULL);

        NSLog (@"End database copying");
        sqlite3_close(unencrypted_DB);
    }
    else {
        sqlite3_close(unencrypted_DB);
        NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
    }
}
like image 374
Kevin_TA Avatar asked Jan 19 '12 18:01

Kevin_TA


People also ask

What encryption does SQLCipher use?

SQLCipher does not implement its own encryption. Instead it uses the widely available encryption libraries like OpenSSL libcrypto, LibTomCrypt, and CommonCrypto for all cryptographic functions.

What is the use of SQLCipher?

Using SQLCipher, an application uses the standard SQLite API to manipulate tables using SQL. Behind the scenes the library silently manages the security aspects, making sure that data pages are encrypted and decrypted as they are written to and read from storage.

Is SQLCipher secure?

SQLCipher is an open source library that provides transparent, secure 256-bit AES encryption of SQLite database files.

Does SQLite support encryption?

SQLite doesn't support encrypting database files by default. Instead, you need to use a modified version of SQLite like SEE, SQLCipher, SQLiteCrypt, or wxSQLite3.


2 Answers

With the latest version of the SQLCipher we have sqlcipher_export() function that can make our code shorter and not connected to the existing database structure:

+ (void)encryptDB
{
    sqlite3 *unencrypted_DB;
    NSString *path_u = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                         stringByAppendingPathComponent:@"dict.sqlite"];

    if (sqlite3_open([path_u UTF8String], &unencrypted_DB) == SQLITE_OK) {
        NSLog(@"Database Opened");
        // Attach empty encrypted database to unencrypted database
        sqlite3_exec(unencrypted_DB, "ATTACH DATABASE 'dict_encrypted.sqlite' AS encrypted KEY '1234';", 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);

        NSLog (@"End database copying");
      sqlite3_close(unencrypted_DB);
    }
    else {
        sqlite3_close(unencrypted_DB);
        NSAssert1(NO, @"Failed to open database with message '%s'.", sqlite3_errmsg(unencrypted_DB));
    }
}
like image 91
slava Avatar answered Sep 21 '22 09:09

slava


  1. Does the encrypted database have to be of type .db? - No, you can use any extension that you want.
  2. Does said encrypted database have to already exist? - No the database does not need to exist already. When you attach a database that doesn't exist it will create a new one
  3. Do I have to provide a path to the file (documents directory, etc)? - Yes, you do need to provide the path to the database, otherwise the current working directory for the app will be used. On iOS you should generally provide the full path to the file name including the app document directory.
  4. Where can I find the successfully encrypted database? - The encrypted database will be located wherever you tell attach to put it. Per #3, if you are building for iOS, include the full path to the document directory in the file name and then the encrypted database will be located there.
like image 21
Stephen Lombardo Avatar answered Sep 21 '22 09:09

Stephen Lombardo