SQLCipher
SQLCipher数据库加密配置说明
本文不涉及代码编写,如有疑问,可参考https://www.zetetic.net/sqlcipher/ios-tutorial/
或者issue联系
为Xcode项目添加SQLCipher
SQLite已经是iOS应用程序中持久数据存储的流行API,因此开发的上升是显而易见的。作为一名程序员,您可以使用一个稳定的,经过充分记录的API,它可以在Objective-C中提供许多好的包装器,如FMDB和加密核心数据。所有安全问题都与应用程序代码完全脱钩,并由底层框架进行管理。
SQLCipher项目的框架代码是开源的,因此用户可以确信应用程序不使用不安全或专有的安全代码。此外,SQLCipher还可以在Android,Linux,OSX和Windows上编译,用于开发跨平台应用程序的用户。
在iOS应用程序中使用SQLCipher是非常简单的。本文档描述了使用CommunityEdition源代码构建过程将SQLCipher集成到现有的iOS项目中。本教程假定您熟悉基本的iOS应用程序开发和Xcode(6.1.1)的工作安装。同样的基本步骤也可以应用于OSX项目。
准备工作
安装Xcode和iOS或者OSX SDK。访问Apple Developer site下载最新的Xcode和iOS、OSX SDKs
OpenSSL
OpenSSL已经不是在iOS或OSX上构建SQLCipher的必要步骤,因为该项目默认使用Apple的CommonCrypto框架进行硬件加速加密。如果您愿意,您仍然可以使用其他加密程序(如OpenSSL)构建SQLCipher,或者您可以自己编写。
SQLCipher
启动终端,cd到你的项目根目录,使用git克隆SQLCipher代码
$ cd ~/Documents/code/SQLCipherApp
$ git clone https://github.com/sqlcipher/sqlcipher.git
Xcode项目配置
将SQLCipher库提供sqlcipher.xcodeproj文件添加到你的项目中,编译成静态库,并链接到项目target上。
添加项目依赖
在Xcode中打开您的iOS应用程序的项目或工作区,在左侧文件目录中找到iOS应用程序的*Project图标并单击选中。右键单击该处,然后选择“Add Files to ‘XXX’”(XXX将根据您的应用程序的名称而有所不同)。由于我们将SQLCipher直接克隆到与iOS应用程序相同的文件夹中,所以您应该在根项目文件夹中看到一个sqlcipher文件夹。打开此文件夹并选择sqlcipher.xcodeproj:
添加Project配置项
开始设置Project的Build settings(注意是Project,而不是Targets),选中Build Settings,搜索“Header Search Paths”,对应的增加路径:$(PROJECT_DIR)/sqlcipher:
接下来,搜索“Other Linker Flags”,对应的增加路径:$(BUILT_PRODUCTS_DIR)/libsqlcipher.a,并拖动放到第一个位置,以确保SQLCipher是第一个被链入你的项目的静态库
然后,搜索“Other C Flags”,对应的增加路径:-DSQLITE_HAS_CODEC,确保SQLCipher能够编译成功
添加Targets配置项
下一步,选择“Targets”,给项目的target增加Target依赖确保SQLCipher在项目代码前面编译,选择”Build phases“
展开”Target Dependencies“,点击+在文件中选择sqlcipher静态库:
展开”Link Binary With Libraries“,点击+在文件中选择libsqlcipher.a静态库:
最后,再给”Link Binary With Libraries“添加”Security.framework“。
Tip:如果libsqlite3.dylib或者其他SQLite库已经存在于”Link Binary With Libraries“列表中,记得要删除掉!!!
如果项目中还有其他主要target,重复上面的步骤即可
集成代码
到此SQLCipher已经配置完毕,接下来就是添加代码,我用的FMDB,本身支持splcipher加密:
- (BOOL)setKey:(NSString*)key {
NSData *keyData = [NSData dataWithBytes:[key UTF8String] length:(NSUInteger)strlen([key UTF8String])];
return [self setKeyWithData:keyData];
}
- (BOOL)setKeyWithData:(NSData *)keyData {
#ifdef SQLITE_HAS_CODEC
if (!keyData) {
return NO;
}
int rc = sqlite3_key(_db, [keyData bytes], (int)[keyData length]);
return (rc == SQLITE_OK);
#else
#pragma unused(keyData)
return NO;
#endif
}
上面摘自FMDatabase.m,可见里面也是用了sqlite3_key();具体就不详细写了。