对数据库加密的思路
1.将内容加密后再写入数据库
这种方式使用简单,在入库/出库只需要将字段做对应的加解密操作即可,一定程度上解决了将数据赤裸裸暴露的问题。
不过这种方式并不是彻底的加密,因为数据库的表结构等信息还是能被查看到。另外写入数据库的内容加密后,搜索也是个问题。
2.对数据库文件加密
将整个数据库整个文件加密,这种方式基本上能解决数据库的信息安全问题。目前已有的SQLite加密基本都是通过这种方式实现的。
使用SQLCipher加密SQLite
logo.jpgSQLCipher是完全开源的,代码托管在github上。SQLCipher使用256-bit AES加密,由于其基于免费版的SQLite,主要的加密接口和SQLite是相同的,但也增加了一些自己的接口。
SQLCipher分为收费版本和免费版本,差别只是集成起来更简单,不用再添加OpenSSL依赖库,而且编译速度更快,从功能上来说没有任何区别。
在项目中集成免费版的SQLCipher略显复杂,还好官网以图文的方式介绍的非常详细,集成过程请参考官网教程。
使用SQLCipher初始化数据库
在使用sqlite3_open打开或创建一个数据库,在对数据库做任何其它操作之前,都必须先使用sqlite3_key输入密码,否则会导致数据库操作失败,报出sqlite错误码SQLITE_NOTADB。
在sqlite3_open打开数据库成功,而且用sqlite3_key输入密码以后,就可以正常的对数据库进行增、删、改、查等操作了。
NSString *databasePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent: @"cipher.db"];
sqlite3 *db;
if (sqlite3_open([databasePath UTF8String], &db) == SQLITE_OK) {
const char* key = [@"abc123" UTF8String];
sqlite3_key(db, key, strlen(key));//注意此行
int result = sqlite3_exec(db, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"password is correct, or, database has been initialized");
[self initTablePerson:db];
[self insert:db];
[self query:db];
} else {
NSLog(@"incorrect password! errCode:%d",result);
}
sqlite3_close(db);
SQLCipher提供了sqlcipher_export()函数,该函数可以方便的对一个普通数据库导入到SQLCipher加密加密的数据库中。
sqlcipher_export()函数同样可以将SQLCipher加密后的数据库内容导入到未加密的数据库中,从而实现解密。
网友评论