SQLite 加密 -- SQLCipher
前言
应用使用 SQLite 来存储数据,很多时候需要对一部分的数据进行加密。常见的做法是对要存储的内容加密后存到数据库中,使用的时候对数据进行解密。这样就会有大量的性能消耗在数据的加密解密上。
SQLite 本身是支持加密功能的 (免费版本不提供加密功能,商业版本是支持加密模块)。SQLCipher 是一个开源的 SQLite 加密的扩展,支持对 db 文件进行 256位的 AES 加密。
加密与非加密的数据库对比
打开 Terminal 输入以下内容,
- ~ $ sqlite3 sqlcipher.db
- sqlite> PRAGMA KEY=’test123′;
- sqlite> CREATE TABLE t1(a,b);
- sqlite> INSERT INTO t1(a,b) VALUES (‘one for the money’, ‘two for the show’);
- sqlite> .quit
- ~$ hexdump -C sqlite.db
结果:
配置步骤
1、到 github 上下载 SQLCipher 插件,并存放到项目根目录下。
2、sqlcipher.xcodeproj 以 static library 的方式添加到项目里面。
3、关联新添加的静态库 (注意,这里不能包含系统的 libsqlite3.dylib)
4、设置 Build Setting
"Header Search Path" 添加,"../sqlcipher/src",这里需要注意路径的关系。
"Other C Flags" 添加 "-DSQLITE_HAS_CODEC"
由于 SQLCipher 是支持 Mac OSX, iOS, WatchOS, TVOS 等多个平台,所以必要的时候,需要修改 sqlcipher.project 的配置文件,否则会引起编译或者 linking 错误,修改如下:
项目中使用示例
- #import <sqlite3.h>
- - (void)openDB2 {
- NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
- NSString *db2Path = [documentPath stringByAppendingPathComponent:db2Name];
- if (sqlite3_open([db2Path UTF8String], &database2) == SQLITE_OK) {
- const char* key = [@"eileen" UTF8String];
- sqlite3_key(database2, key, strlen(key));
- // if (sqlite3_exec(database2, (const char*) "CREATE TABLE t1 (a, b);", NULL, NULL, NULL) == SQLITE_OK) {
- // NSLog(@"password is correct, or, database has been initializ");
- //
- // } else {
- // NSLog(@"incorrect password!");
- // }
- // sqlite3_close(database2);
- if (sqlite3_exec(database2, "INSERT INTO t1(a, b) VALUES('qqqqqqq', 'pppppp')", NULL, NULL, NULL)==SQLITE_OK) {
- NSLog(@"密码正确");
- }
- else {
- NSLog(@"密码错误");
- }
- sqlite3_stmt *statement = NULL;
- sqlite3_prepare_v2(database2, "SELECT a,b FROM t1", -1, &statement, NULL);
- while (sqlite3_step(statement) == SQLITE_ROW) {
- char *field0 = (char*)sqlite3_column_text(statement, 0);
- NSString *field0Str = @"";
- if (field0) {
- field0Str = [NSString stringWithUTF8String:field0];
- }
- char *field1 = (char*)sqlite3_column_text(statement, 1);
- NSString *field1Str = @"";
- if (field1) {
- field1Str = [NSString stringWithUTF8String:field1];
- }
- NSLog(@"a = %@, b = %@;", field0Str, field1Str);
- }
- sqlite3_finalize(statement);
- }
- else {
- sqlite3_close(database2);
- }
- }
Terminal 上安装 SQLCipher
总的来说在 Terminal 执行以下 2句即可,参照:
- $ ./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto" ;# Run the configure script
- $ make ;# Run the makefile.
1、cd 到下载好的 sqlcipher 目录下,并执行
- $ ./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"
2、输入
- $ make
2.1、发生了错误,
sqlite3.c:18280:10: fatal error: 'openssl/rand.h' file not found
#include <openssl/rand.h>
见下图:
解决方法,输入:
- $ brew link openssl --force
2.2、发生错误,“-bash: brew: command not found”,证明 OS 尚未安装 Homebrew。(安装 Homebrew 的前提下是安装了 Xcode, 并且 Command Line Tools 已安装, Terminal 输入 "gcc --version" 检查)
解决方法,输入:
- $ -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.3、安装好 Homebrew 后,重新执行
- $ brew link openssl --force
发生了错误:Error: No such keg: /usr/local/Cellar/openssl
解决方法,使用 brew 安装 openssl,输入:
- $ brew install openssl
2.4、安装完 openssl 后,重新执行
- $ brew link openssl --force
执行完后,再重新执行
- $ make
多次执行 make 操作会发生错误 “make: Nothing to be done for `all'”,解决方法,输入:
- $ make clean
- // 重新执行
- $ make
3、执行完前面 2 步,sqlcipher 目录下会多了一个 sqlcipher 文件,用于 Terminal 中管理数据库。
Terminal 查看和修改数据库的密码管理
cd 到刚才新生成的 sqlcipher 文件的目录下,执行以下的操作,参照。
1、使用 SQLCipher 加密已经存在的数据库
- $ ./sqlcipher plaintext.db
- sqlite> ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'testkey';
- sqlite> SELECT sqlcipher_export('encrypted');
- sqlite> DETACH DATABASE encrypted;
2、解除使用 SQLCipher 加密的数据库密码
- $ ./sqlcipher encrypted.db
- sqlite> PRAGMA key = 'testkey';
- sqlite> ATTACH DATABASE 'plaintext.db' AS plaintext KEY ''; -- empty key will disable encryption
- sqlite> SELECT sqlcipher_export('plaintext');
- sqlite> DETACH DATABASE plaintext;
注意
有些软件的加密方式是不公开的,例如 Mac SQLiteManager 生成的加密的 .db 文件没法在程序里面解密打开。程序里面生成的加密的 .db 文件也没法用 Mac 上的 SQLiteManager 打开。
免费版本的项目代码不提供以下的功能:
- 数据库创建的时候,没有使用 sqlite3_key 设置密码,之后不能添加密码管理;
- 对创建时已经设置了密码管理的数据库,不能取消其密码管理,只能重新设置新的密码;
SQLite 加密 -- SQLCipher的更多相关文章
- Android中对sqlite加密--SQLCipher
原文:Android中对sqlite加密--SQLCipher android中有些时候会将一些隐私数据存放在sqlite数据库中,在root过的手机中通过RE就能够轻松的打开并查看数据库所有内容,所 ...
- SQLite加密方式 [转]
关于SQLite SQLite是一个轻量的.跨平台的.开源的数据库引擎,它的在读写效率.消耗总量.延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案(如iOS.Android). ...
- SQLite加密 wxSqlite3
一直在网上搜wxSqlite3的文档,但是总找不到能真正解决问题的,就是一个简单的编译wxSqlite3自带的示例也出了老多问题,后来却发现,其实wxSqlite3的readme中已经有了详细的方法, ...
- iOS Sqlite加密(FMDB/SQLCipher)
/** * 对数据库加密 * * @param path path description * * @return return value description */ + (BOOL)encryp ...
- sqlite加密
一直使用sqlite来管理本地的数据,但是Xcode中的SDK中集成的sqlite是免费的,不提供加密模块,但是程序中用到的很多数据,有时候是不想让别人看到,一开始虑修改sqlite的源码,自己重新编 ...
- SQLite加密的方法(c#)
http://blog.csdn.net/xjbx/article/details/2712236 设置下密码就可以了 http://bbs.csdn.net/topics/380018685 编译为 ...
- Android数据库(sqlite)加密方案
最近因为一些项目的安全性需要将数据库加密,一开始想到的就是先将数据库通过AES加密,然后运行时再解密,另一种是将数据库里的内容加密. 很快这两种方案都是不理想的,第一种加密方式形同虚设,第二种,如果加 ...
- [转]正确使用SQLCipher来加密Android数据库 - 朝野布告
参考文档:http://www.tuicool.com/articles/eYNFbuA Android本身自带有不加密的数据库SQLite,如果要保存密码之类的敏感数据在本地的话方法一是使用字段加密 ...
- 正确使用SQLCipher来加密Android数据库
Android本身自带有不加密的数据库SQLite,如果要保存密码之类的敏感数据在本地的话方法一是使用字段加密解密算法,方法二是整个数据库都加密掉.如果只是加密解密某个字段(如password)就推荐 ...
随机推荐
- Class.forName的使用
Class.forName的使用 Class.forName返回一个类,使用此方法可以获取类 首先,创建一个Student类 /*** * This Class is for Student bean ...
- MySQL 5.7 mysqlpump 备份工具说明
背景: MySQL5.7之后多了一个备份工具:mysqlpump.它是mysqldump的一个衍生,mysqldump就不多说明了,现在看看mysqlpump到底有了哪些提升,可以查看官方文档,这里针 ...
- OUC校园导游
大二专业课太多,都没有好好的在博客上面做笔记,以备后面用的时候可以查找看一下,下面是写的不是完全正确的与图相关的代码~~希望指正~~ /* Name: Copyright: Author:Hxm Da ...
- .NET LINQ Set 运算
Set 运算 LINQ 中的 Set 操作是指根据相同或不同集合(或集)中是否存在等效元素来生成结果集的查询操作. 方法 方法名 说明 C# 查询表达式语法 Visual Basic 查询表 ...
- ios 消息通知
苹果的通知分为本地通知和远程通知,这里主要说的是远程通知 历史介绍 iOS 3 - 引入推送通知UIApplication 的 registerForRemoteNotificationTypes 与 ...
- 整合SSM时报错:java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()Ljava/lang/Integer;
在整合Spring和MyBatis时,只进行了简单的插入操作,结果报了这个错,顿时整个人都崩溃了 -- 一点都看不懂嘛!只有网上搜索 结果是在使用MyBatis3.x和Spring4.x整合是 导入的 ...
- Win10 UWP vs add github
vs github 插件 教程 官方教程 点击查看存储库,跳转到 DemoHttp for github
- OneThink开发框架
OneThink是一个开源的内容管理框架,基于最新的ThinkPHP3.2版本开发,提供更方便.更安全的WEB应用开发体验,采用了全新的架构设计和命名空间机制,融合了模块化.驱动化和插件化的设计理念于 ...
- 关于 《cocoapods 的taobao的镜像停止更新问题》
cocoapods 的ruby.taobao.org 停止更新了!!!!!! 最近一直在改老项目,突然听伙伴说:cocoapods 的ruby.taobao.org 停止更新了.很是吃惊,遂即闯入:h ...
- IE、FF、Chrome浏览器中的JS差异介绍
FF.Chrome:没有window.event对象 FF.Chrome:没有window.event对象,只有event对象,IE里只支持window.event,而其他主流浏览器两者都支持,所以 ...