我正在尝试使用SQLCipher将未加密的sqlite3数据库的内容添加到加密的数据库中。我的基础是this和this。然而,有些事情我不清楚。
在第ATTACH DATABASE
行中,加密数据库的类型是.db
吗?可以.sqlite
匹配我的原始数据库吗?
说加密数据库必须已经存在吗?如果是这样,它应该在应用程序中的哪个位置?我是否必须提供文件路径(文档目录等)?
在哪里可以找到成功加密的数据库?它会在哪里保存?
这是我的代码:
+ (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 :(得分:6)
使用最新版本的SQLCipher,我们有sqlcipher_export()函数可以缩短代码并且不会连接到现有的数据库结构:
+ (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 :(得分:5)
答案 2 :(得分:0)
好吧,我从来没有完成ATTACH DATABASE
,我使用的SQLCiper版本可能与你的不同,但是(对于我所处理的SQLCipher的实现),文件打开逻辑是标准的SQLite,其行为与没有SQLCipher的行为相同。
所以你不需要.db
的后缀或其他任何特定的后缀 - 你可以使用你想要的任何东西。
在发出REKEY
之前,任何新数据库都完全“正常”,并且将以“正常”方式为SQLite创建/删除。
重新ATTACH DATABASE
,我怀疑最好首先创建数据库(和REKEY
),然后附加它。