iOS SQLite加密之SQLCipher

  至于SQLCipher,我就不多说了,百度一下,你就知道。公司的iOS APP要给SQLite,今天就上网查了些资料,做了下整理,主要参考SQLCipher的官方集成文档,有不妥之处大家提出来我再改进,感谢拍砖。官方集成文档:https://www.zetetic.net/sqlcipher/ios-tutorial/。

Prerequisites

安装Xcode开发环境,不用多说了吧。

OpenSSL

本教程用苹果提供的FrameWork:CommonCrypto,可在工程,Target,Build Phases ,Link Binary 中添加,搜索 CommonCrypto即可添加。

SQLCipher

打开终端,切到你要集成sqlcipher的工程根目录下,执行下命令。从GitHub下载 SQLCipher到本地:

$ cd ~/Documents/code/SQLCipherApp
$ git clone https://github.com/sqlcipher/sqlcipher.git

Xcode Project Configuration

The SQLCipher source provides a sqlcipher.xcodeproj project file that we‘ll add to your project to build a static library that you‘ll link from your main application target.

Add Project Reference

选择你的项目,右键,选择 "Add Files to [你的工程]";在弹出的选择窗口找到你刚才从git下载的sqlcipher路径,打开sqlcipher文件夹,选择sqlcipher.xcodeproj;

注意:不要勾选 Copy items if needed 复选框。

Configure Target Dependencies and Link Binary With Libraries

点击工程,选择TARGETS中你的工程,点击 Build Phases Tab栏。

1. 展开 Target Dependencies ,添加 + sqlcipher 静态库

2.展开 Link Binary With Libraries,添加+libsqlcipher.a库

注意:如果你的工程库中已经添加了libsqlite3.dylib 或者其他的SQLite库,请Remove掉,否则可能会提示出现重复sqlite库。

重复这些步骤在你工程的其他Target中。

Configure Build Settings

回到你的工程编辑面板,选择工程,TARGETS》你的工程Target,Build Settings Tab栏,

1.选择Header Search Paths项,双击键入新值:./sqlcipher/src。如图:

注意填写的路径。../表示上级文件夹

2.选择 Other C Flags ,双击 添加-DSQLITE_HAS_CODEC。注意Release 和 Debug的配置值一样,如下图:

注意(自己翻译吧):Hot Tip: The handling of Architectures and the meaning of the $(STANDARD_ARCHS) build variable changes depending on the Xcode release, but currently on iOS in Xcode 6.1.1 the armv7s architecture is not included in your build. SQLCipher supports this architecture! If you need to squeeze that much more speed out of SQLCipher on those devices, add the armv7s architecture string to your Architectures option in Build Settings (sample image here).

Integration Code

到现在为止,sqlcipher已经包含到我们的工程中了,现在我们可以使用sqlcipher来创建或打开一个加密sqlite书库了。接下来打开程序的代理类,引入sqlite3.h头文件,找到-applicationDidFinishLaunching:withOptions:代理方法,开始设置代码如下:

//
//  AppDelegate.m
//  SecureLoginDelegate
//
//  Created by Billy Gray on 10/19/14.
//  Copyright (c) 2014 Zetetic. All rights reserved.
//

#import "AppDelegate.h"
#import <sqlite3.h>

@interface AppDelegate ()
@property (nonatomic) BOOL isLoginViewControllerDisplayed;
@property (readonly) NSURL *databaseURL;
@property (readonly) BOOL databaseExists;
@end

@implementation AppDelegate
@dynamic databaseURL;
@dynamic databaseExists;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Set up the window with loginViewController as the rootViewController for now
    // to avoid showing app view on launch on iOS 8
    [[self window] setRootViewController:self.loginViewController];
    [[self window] makeKeyAndVisible];
    self.isLoginViewControllerDisplayed = YES;

    // Set up a SQLCipher database connection:
    sqlite3 *db;
    if (sqlite3_open([[self.databaseURL path] UTF8String], &db) == SQLITE_OK) {
        const char* key = [@"StrongPassword" UTF8String];
        sqlite3_key(db, key, (int)strlen(key));
        if (sqlite3_exec(db, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
            NSLog(@"Password is correct, or a new database has been initialized");
        } else {
            NSLog(@"Incorrect password!");
        }
        sqlite3_close(db);
    }
    return YES;
}

- (NSURL *)databaseURL {
    NSArray *URLs = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *directoryURL = [URLs firstObject];
    NSURL *databaseURL = [directoryURL URLByAppendingPathComponent:@"secure.db"];
    return  databaseURL;
}

- (BOOL)databaseExists {
    BOOL exists = NO;
    NSError *error = nil;
    exists = [[self databaseURL] checkResourceIsReachableAndReturnError:&error];
    if (exists == NO && error != nil) {
        NSLog(@"Error checking availability of database file: %@", error);
    }
    return exists;
}
@end

SecureLoginDelegate-AppDelegate.m hosted with ? by GitHub

OK,编译Run你的App,配置不错的话就能运行成功了,在控制台你若能看到打印如下的日志内容:

虽然我们建议你用sqlite3_bind_* API 来避免一些陷阱,你也可以执行PRAGMA key = ‘some key‘; as SQL。

下面还有一段英文自己看吧:

The call to sqlite3_key or "PRAGMA key" should occur as the first operation after opening the database. In most cases SQLCipher uses PBKDF2, a salted and iterated key derivation function, to obtain the encryption key. Alternately, an application can tell SQLCipher to use a specific binary key in blob notation (note that SQLCipher requires exactly 256 bits of key material), for example:

PRAGMA key = "x‘2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99‘";

Once the key is set SQLCipher will automatically encrypt all data in the database! Note that if you don‘t set a key then SQLCipher will operate identically to a standard SQLite database.

After the application is wired up to use SQLCipher, take a peek at the resulting data files to make sure everything is in order. An ordinary SQLite database will look something like the following under hexdump. Note that the file type, schema, and data are clearly readable.

% hexdump -C plaintext.db
00000000  53 51 4c 69 74 65 20 66  6f 72 6d 61 74 20 33 00  |SQLite format 3.|
00000010  04 00 01 01 00 40 20 20  00 00 00 04 00 00 00 00  |[email protected]  ........|
...
000003b0  00 00 00 00 24 02 06 17  11 11 01 35 74 61 62 6c  |....$......5tabl|
000003c0  65 74 32 74 32 03 43 52  45 41 54 45 20 54 41 42  |et2t2.CREATE TAB|
000003d0  4c 45 20 74 32 28 61 2c  62 29 24 01 06 17 11 11  |LE t2(a,b)$.....|
000003e0  01 35 74 61 62 6c 65 74  31 74 31 02 43 52 45 41  |.5tablet1t1.CREA|
000003f0  54 45 20 54 41 42 4c 45  20 74 31 28 61 2c 62 29  |TE TABLE t1(a,b)|
...
000007d0  00 00 00 14 02 03 01 2d  02 74 77 6f 20 66 6f 72  |.......-.two for|
000007e0  20 74 68 65 20 73 68 6f  77 15 01 03 01 2f 01 6f  | the show..../.o|
000007f0  6e 65 20 66 6f 72 20 74  68 65 20 6d 6f 6e 65 79  |ne for the money|

Fire up the SQLCipher application in simulator and look for the application database files under/Users/billy/Library/Developer/CoreSimulator/Devices/<SOME ID NUMBER>/data/Containers/Data/Application/<SOME ID NUMBER>/Documents(step through the code in the debugger and enter po [self.databaseURL path] for the exact path). Try running hexdump on the application database. With SQLCipher the output should looks completely random, with no discerning characteristics at all.

% hexdump -C sqlcipher.db
00000000  1b 31 3c e3 aa 71 ae 39  6d 06 f6 21 63 85 a6 ae  |.1<..q.9m..!c...|
00000010  ca 70 91 3e f5 a5 03 e5  b3 32 67 2e 82 18 97 5a  |.p.>.....2g....Z|
00000020  34 d8 65 95 eb 17 10 47  a7 5e 23 20 21 21 d4 d1  |4.e....G.^# !!..|
...
000007d0  af e8 21 ea 0d 4f 44 fe  15 b7 c2 94 7b ee ca 0b  |..!..OD.....{...|
000007e0  29 8b 72 93 1d 21 e9 91  d4 3c 99 fc aa 64 d2 55  |).r..!...<...d.U|
000007f0  d5 e9 3f 91 18 a9 c5 4b  25 cb 84 86 82 0a 08 7f  |..?....K%.......|
00000800  

See Also

All applications that make use of cryptography, including those that use SQLCipher or iOS internal libraries like CommonCrypto and Keychain, must provide documentation to Apple that demonstrates review by the Department of Commerce (DOC) Bureau of Industry and Security (BIS) and classification of the application a mass market encryption item.

Information on the PBKDF2 key derivation function is available at http://en.wikipedia.org/wiki/PBKDF2

时间: 2024-10-18 02:31:51

iOS SQLite加密之SQLCipher的相关文章

SQLite 加密 -- SQLCipher

SQLite3 插件 github 下载地址 插件配置步骤地址 购买地址 其他加密方式介绍 SQLCipher API 地址 前言 应用使用 SQLite 来存储数据,很多时候需要对一部分的数据进行加密.常见的做法是对要存储的内容加密后存到数据库中,使用的时候对数据进行解密.这样就会有大量的性能消耗在数据的加密解密上. SQLite 本身是支持加密功能的 (免费版本不提供加密功能,商业版本是支持加密模块).SQLCipher 是一个开源的 SQLite 加密的扩展,支持对 db 文件进行 256

SQLite加密方式 [转]

关于SQLite SQLite是一个轻量的.跨平台的.开源的数据库引擎,它的在读写效率.消耗总量.延迟时间和整体简单性上具有的优越性,使其成为移动平台数据库的最佳解决方案(如iOS.Android). 然而免费版的SQLite有一个致命缺点:不支持加密.这就导致存储在SQLite中的数据可以被任何人用任何文本编辑器查看到. SQLite加密方式 对数据库加密的思路有两种: 1. 将内容加密后再写入数据库 这种方式使用简单,在入库/出库只需要将字段做对应的加解密操作即可,一定程度上解决了将数据赤裸

iOS代码加密常用加密方式

在今天的面试中,被问到了iOS是采用什么进行加密解密操作的,我的回答是这样的:AES,MD5,Base 64,然后是对这几种加密算法进行了一下简单的介绍和概述和几种算法之间的不同点和优缺点.然而,收到的回答是:这些都不是iOS的加密!我顿时就无语了,这不就是iOS加密所用到的方法么?然后向面试官请教了一下:MD5是一种摘要....什么叫加密呢?加密是客户端对数据加密和服务器端采用秘钥对数据进行解密处理,为了数据的安全考虑.要说加密应该是RSA.幸亏之前有了解过RSA,只是了解的不是很彻底和清楚.

iOS——常用加密方式

iOS代码加密常用加密方式,常见的iOS代码加密算法包括MD5加密.AES加密.BASE64加密. 三大算法iOS代码加密是如何进行加密的: /////////////////////////////////////////////////////////////////// MD5 iOS代码加密使用方法 /////////////////////////////////////////////////////////////////// //创建MD5类,代码如下 #import <Foun

iOS代码加密的几种方式

众所周知的是大部分iOS代码一般不会做加密加固,因为iOS APP一般是通过AppStore发布的,而且苹果的系统难以攻破,所以在iOS里做代码加固一般是一件出力不讨好的事情.万事皆有例外,不管iOS.adr还是js,加密的目的是为了代码的安全性,虽然现在开源畅行,但是不管个人开发者还是大厂皆有保护代码安全的需求,所以iOS代码加固有了生存的土壤.下面简单介绍下iOS代码加密的几种方式. iOS代码加密的几种方式 1.字符串加密 字符串会暴露APP的很多关键信息,攻击者可以根据从界面获取的字符串

iOS base64加密解密

本文转载至 http://jingyan.baidu.com/article/93f9803fff45c9e0e46f5596.html 从参考资料的地址中下载GTMBase64.zip库文件包,并解压,获得GTMBase64.h,GTMBase64.m和GTMDefines.h三个文件. 将解压得到的三个文件,添加到项目中. 新建一个base64的类,在base64.h中天假四个函数: + (NSString*)encodeBase64String:(NSString*)input; + (N

iOS rsa加密与解密

转自 --响铃  IOS rsa加密与解密 ras加密需要两组秘钥,一组公共秘钥,一组私有秘钥. 生成命令: openssl req -x509 -out public_key.der -outform der -new -newkey rsa:2048 -keyout private_key.pem public_key.der为公共秘钥文件,private_key.pem为私有秘钥文件. 生成ios可引用的私有秘钥文件.pfx: 1. OpenSSL rsa -in private_key.

iOS常用加密方式

示例项目下载地址  https://github.com/cerastes/Encryption 1MD5 创建MD5类 #import <Foundation/Foundation.h> @interface CJMD5 : NSObject +(NSString *)md5HexDigest:(NSString *)input; @end #import "CJMD5.h" #import <CommonCrypto/CommonDigest.h> @imp

iOS sqlite数据库实现(转)

转载自:http://www.cnblogs.com/macroxu-1982/archive/2012/10/01/2709960.html 1 实现过程添加libsqlite3组件 选择项目后,在展示的xcodepro文件配置界面中配置 build phases -> Link Binary With Libraries -->+ -->libsqlite3.dylib 2 在当前项目中添加sqlite 数据库 3 实现app运行时,将sqlite文件复制到沙盒中 4 实现查询数据库