2012-01-19 125 views
4

我試圖使用SQLCipher將未加密sqlite3數據庫的內容添加到加密數據庫。我已經基於我想要做的thisthis。然而,有些事情對我來說還不清楚。使用SQLCipher將加密數據庫附加到未加密數據庫

  1. 在線路ATTACH DATABASE,不加密的數據庫必須是.db類型?它可以是.sqlite匹配我的原始數據庫?

  2. 請問加密數據庫是否已經存在?如果是這樣,它應該在應用程序中的位置?我是否必須提供文件路徑(文檔目錄等)?

  3. 我在哪裏可以找到成功加密的數據庫?它將在哪裏得到保存?

這裏是我的代碼:

+ (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)); 
    } 
} 
+0

我想我很好奇,爲什麼你第二個參考文獻說要使用這種技術而不是僅僅用「REKEY」來加密現有的數據庫。我們的SQLCipher實現可以很好地處理現有數據庫的「REKEY」。 –

回答

5
  1. 加密數據庫是否必須是.db類型? -不,您可以使用任何您想要的擴展名。
  2. 請問加密數據庫是否已經存在? -否數據庫不需要已經存在。當你附加一個不存在的數據庫時,它會創建一個新的數據庫
  3. 我必須提供一個文件路徑(文件目錄等)嗎? - 是的,您確實需要提供數據庫的路徑,否則將使用該應用程序的當前工作目錄。在iOS上,您通常應該提供文件名的完整路徑,包括應用程序文檔目錄。
  4. 我在哪裏可以找到成功加密的數據庫? - 加密的數據庫將位於您告訴附加的地方。根據#3,如果您正在爲iOS構建,請在文件名中包含文檔目錄的完整路徑,然後加密數據庫將位於此處。
+1

優秀的答案。非常感謝你。我的另一個問題是我應該在一個單獨的程序中加密數據庫,並將該數據庫添加到我想要使用它的應用程序中? –

0

嗯,我從來沒有做過ATTACH DATABASE,我已經使用了SQLCiper的版本是從你可能不同,但(對於SQLCipher的實現我已經處理過),文件打開邏輯是標準SQLite,並且行爲方式與沒有SQLCipher相同。

所以你不應該需要.db或其他任何特定的後綴 - 你可以使用任何你想要的。

在您發出REKEY之前,任何新的數據庫都是完全「正常」的,並且會以SQLite的「正常」方式創建/刪除。

Re ATTACH DATABASE,我懷疑最好先創建DB(和REKEY it),然後再附加它。

6

隨着最新版本,我們sqlcipher_export()函數SQLCipher的,可以使我們的代碼更短,並沒有連接到現有的數據庫結構:

+ (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)); 
    } 
} 
+1

''ATTACH DATABASE'dict_encrypted.sqlite'AS encrypted KEY'1234';'dict_encrypted.sqlite應該替換文檔的路徑。 – welsonla