博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQLite 加密 -- SQLCipher
阅读量:5876 次
发布时间:2019-06-19

本文共 4535 字,大约阅读时间需要 15 分钟。

  

 

前言

  应用使用 SQLite 来存储数据,很多时候需要对一部分的数据进行加密。常见的做法是对要存储的内容加密后存到数据库中,使用的时候对数据进行解密。这样就会有大量的性能消耗在数据的加密解密上。

  SQLite 本身是支持加密功能的 (免费版本不提供加密功能,商业版本是支持加密模块)。SQLCipher 是一个开源的 SQLite 加密的扩展,支持对 db 文件进行 256位的 AES 加密。

  

加密与非加密的数据库对比

  打开 Terminal 输入以下内容,

~ $ sqlite3 sqlcipher.dbsqlite> 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 
- (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 的前提下是安装了 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 encryptionsqlite> SELECT sqlcipher_export('plaintext'); sqlite> DETACH DATABASE plaintext;

  

 

注意

  有些软件的加密方式是不公开的,例如 Mac SQLiteManager 生成的加密的 .db 文件没法在程序里面解密打开。程序里面生成的加密的 .db 文件也没法用 Mac 上的 SQLiteManager 打开。

  免费版本的项目代码不提供以下的功能:

  • 数据库创建的时候,没有使用 sqlite3_key 设置密码,之后不能添加密码管理;
  • 对创建时已经设置了密码管理的数据库,不能取消其密码管理,只能重新设置新的密码;

 

转载于:https://www.cnblogs.com/eileenleung/p/5456907.html

你可能感兴趣的文章
遇到的那些坑
查看>>
央行下属的上海资信网络金融征信系统(NFCS)签约机构数量突破800家
查看>>
[转] Lazy evaluation
查看>>
常用查找算法总结
查看>>
被神话的大数据——从大数据(big data)到深度数据(deep data)思维转变
查看>>
修改校准申请遇到的问题
查看>>
Linux 进程中 Stop, Park, Freeze【转】
查看>>
文件缓存
查看>>
远程协助
查看>>
Scrum实施日记 - 一切从零开始
查看>>
关于存储过程实例
查看>>
配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler” 解决办法...
查看>>
AIX 7.1 install python
查看>>
PHP盛宴——经常使用函数集锦
查看>>
重写 Ext.form.field 扩展功能
查看>>
Linux下的搜索查找命令的详解(locate)
查看>>
福利丨所有AI安全的讲座里,这可能是最实用的一场
查看>>
开发完第一版前端性能监控系统后的总结(无代码)
查看>>
Python多版本情况下四种快速进入交互式命令行的操作技巧
查看>>
MySQL查询优化
查看>>