今天本想寫一片 GAE+goAgent+SwitchySharp 的指南的!但是突然翻出了前段時間寫的關於iOS中的SQL數據庫文件加密的代碼,於是乎決定今天就先講講這個!~ 那麼goAgent將放在周末,後續的文章中除了文件加密,還有傳輸數據加密,感興趣的童鞋 敬請留意。
言歸正傳,sql的文件加密,我們首先要用到一個庫,它就是大名鼎鼎的Sqlcipher, 奉上連接:http://sqlcipher.NET,在ios裡 我們需要看的文檔是這一篇http://sqlcipher.Net/ios-tutorial/,文檔是全英文的,在此,不詳細闡述,只按步驟教大家怎麼做,至於為什麼做的問題,就需要自己去尋找答案了!
1.下載需要的庫 這裡我們總共需要3個目錄的文件,分別是sqlcipher,openssl-xcode,openssl-1.0.0e。
首先下載第一個
% cd ~/Documents/code//命令行cd到你要下載的目錄 % curl -o openssl-1.0.0e.tar.gz http://www.openssl.org/source/openssl-1.0.0e.tar.gz//下載 % tar xzf openssl-1.0.0e.tar.gz //解壓縮
附:
SQLCipher uses the widely trusted and peer-reviewed OpenSSL library for all cryptographic functions including the AES-256 algorithm, pseudo random number generation, and PBKDF2 key derivation. OpenSSL isn't framework that is usable directly on the iPhone so we will setup our project to build and link against it as a static library.
Download the 1.0.x stable version from http://www.openssl.org/source/ and extract it to a folder on your system. Since the same OpenSSL source tree may be shared across multiple SQLCipher projects, it's a good idea to place this in some shared location outside of your project folder. Justs make a note of the source directory path for later.
(看不懂英文的童鞋也不用著急,跟著繼續做就好了,也很好理解)
OpenSSL是套開源的SSL套件,其函數庫是以C語言所寫,實現基本的傳輸層資料加密功能。
第二個
% cd ~/Documents/code/SQLCipherApp % git clone https://github.com/sqlcipher/sqlcipher.git
從遠端服務器將其 clone 下來,這裡推薦放到和上一個文件同一個目錄 方便管理
這個就是 sqlcipher 的project code了
第三個
% cd ~/Documents/code/SQLCipherApp % git clone https://github.com/sqlcipher/openssl-xcode.git
這個是我們需要動態編譯進工程的文件
至此我們需要的文件 就准備好了
接下來 打開你的工程進行配置,
(這裡我是自己單獨寫了一個工具用來加密並生成!後面會附上我的源碼)
1.將你下載的3個目錄拷貝進你的工程目錄
2.點擊你xcode的設置頁,選擇locations ->source trees
點擊+號 settingname and display name 均設為 “OPENSSL_SRC” path設置為你工程目錄下openssl-1.0.0e的所在路徑
3.添加子項目的引用
將剛才下載的文件裡的openssl.xcodeproj 和sqlcipher.xcodeproj (分別在openssl-xcode文件和sqlcipher文件下)添加到你的主工程下,建立引用,直接看圖吧!
4,接下來 配置編譯依賴的庫,這是必須的!~
點擊你的工程TARGETS 進入build phases ->target dependencies,添加圖中的兩個項目
接下來點擊同一個頁面下的link binary with libraries添加這兩個庫
至此 還有最後一步,設置編譯設置
點擊你的工程project->build settings ->搜索architectures進行設置
我這裡由於是mac程序看起來會是這樣
iOS的話 會是這樣
(關於這裡的設置,如果又不明白的地方 請google)
接下來 還是在同頁面 搜索“other c flags”
進行如下配置
至此整個過程就打工告成了
接下來講述使用
首先在需要的文件內 import<sqlite3.h>
下面 示范一個 創建or打開數據庫的函數
-(BOOL) openDatabase { if (sqlite3_open([[self dataFilePath:DB_NAME] UTF8String], &_database) == SQLITE_OK) { const char* key = [@",66c9a^N" UTF8String]; //數據庫文件加密 sqlite3_key(_database, key, (int)strlen(key)); //數據庫文件加密 NSLog(@"\n===數據庫打開or創建成功===\n"); return YES; }else{ NSLog(@"\n===數據庫打開失敗===\n"); } return NO; } DB_NAME 是定義的 數據庫文件名的宏",66c9a^N" 是你要設置的數據庫密鑰 sqlite3_key(_database, key, (int)strlen(key));這個方法裡就包含了 加解密的過程!~是不是非常簡單呢嘿嘿接下來 附上自己的工程 源代碼有需要的童鞋,就自己看看吧!裡面有詳細的注釋, 也簡單的實現了幾個方便數據庫操作的函數 ////////////////////////////////////////////////////////// #import <Foundation/Foundation.h> #import <sqlite3.h> #define DB_NAME @"xxxxxxx.db" //數據庫文件名 @interface SqliteHelp :NSObject @propertysqlite3 *database; //數據庫句柄 @propertysqlite3_stmt *statement; //sql語句 @property char *errmsg; -(BOOL) openDatabase; //打開數據庫 這個函數一般不直接調用,而是直接調用對數據庫操作的函數 -(void) closeDataBase; //關閉數據庫 這個函數一般不直接調用,而是直接調用對數據庫操作的函數 -(NSString *) dataFilePath:(NSString *)fileName; //返回數據庫存儲路徑 這個函數一般不直接調用,而是直接調用對數據庫操作的函數 /** * 說明: 給定一個SQL語句 插入或者編輯一個數據 * 語句格式 : * 插入:[insert (文件名)values(data1, data2, data3, ...);] * 編輯:[update(文件名) set (字段名)=(修改後的數據) where(字段名)=(修改前的數據);] */ -(BOOL) insertOrUpdateData:(NSString *)sql; -(NSMutableArray *) getUsers; //以數組的形勢,獲取所有用戶 -(int) getCountOfDatabase; //獲取當前數據庫的數量 @end //////////////////////////////////////////////////// #import "SqliteHelp.h" @implementation SqliteHelp @synthesize database =_database; @synthesize statement =_statement; @synthesize errmsg =_errmsg; -(BOOL) openDatabase { if (sqlite3_open([[selfdataFilePath:DB_NAME]UTF8String], &_database) ==SQLITE_OK) { constchar* key = [@",66c9a^N"UTF8String]; //數據庫文件加密 sqlite3_key(_database, key, (int)strlen(key)); //數據庫文件加密 NSLog(@"\n===數據庫打開or創建成功===\n"); returnYES; }else{ NSLog(@"\n===數據庫打開失敗===\n"); } return NO; } -(void) closeDataBase { sqlite3_close(_database); } -(NSString *) dataFilePath:(NSString *)fileName { NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [pathsobjectAtIndex:0]; return [documentsDirectorystringByAppendingPathComponent:fileName]; } -(BOOL) insertOrUpdateData:(NSString *)sql { if ([selfopenDatabase]) { if (sqlite3_exec(_database, [sqlUTF8String],nil, &_statement, &_errmsg) !=SQLITE_OK) { NSLog(@"\n===插入數據失敗===\n"); NSLog(@"\n==sql Error:%s",_errmsg); returnNO; }else{ NSLog(@"\n===插入數據成功===\n"); returnYES; } } sqlite3_close(_database); return NO; } -(NSMutableArray *) seeDatabase { NSMutableArray *users = [[NSMutableArrayalloc]init]; NSString *sql = [NSStringstringWithFormat:@"SELECT * FROM t_relive"]; if ([selfopenDatabase]) { if (sqlite3_prepare_v2(_database, [sqlUTF8String], -1, &_statement,nil) ==SQLITE_OK) { while (sqlite3_step(_statement) ==SQLITE_ROW ) { // User *user = [[Question alloc] init]; int name =sqlite3_column_int(_statement,0); // [user setName:[NSString stringWithUTF8String:name]]; int index =sqlite3_column_int(_statement,1); // [user setId:[[NSString stringWithUTF8String:index] intValue]]; // [users addObject: user]; NSLog(@"%i=%i",name,index); } sqlite3_finalize(_statement); } } sqlite3_close(_database); return users; } -(int) getCountOfDatabase { int count =0; NSString *sql = [NSStringstringWithFormat:@"SELECT * FROM User"]; if ([selfopenDatabase]) { if (sqlite3_prepare_v2(_database, [sqlUTF8String], -1, &_statement,nil) ==SQLITE_OK) { while (sqlite3_step(_statement) ==SQLITE_ROW) { count ++; } sqlite3_finalize(_statement); } } return count; } @end ///////////////////////////////////////////////////////////////// 這裡實現 輸入sql表 生成數據庫,可以在控制台查錯 #import "AppDelegate.h" #import "SqliteHelp.h" @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application [selfbuildDatabase]; [selfinsertDatabase]; } - (void) buildDatabase { NSError *error; NSString *textFile = [NSStringstringWithContentsOfFile:[[NSBundlemainBundle]pathForResource:@"schema.sqlite.tables.sql"ofType:nil]encoding:NSUTF8StringEncodingerror:&error]; if (textFile ==nil) { NSLog(@"Error reading text file. %@", [errorlocalizedFailureReason]); } NSArray *row = [textFilecomponentsSeparatedByString:@";"]; NSInteger count = [rowcount]; SqliteHelp *t = [SqliteHelpnew]; for (int i=0; i<count; i++) { NSString *tempString = [NSStringstringWithFormat:@"%@;",row[i]]; NSLog(@"%@",tempString); [tinsertOrUpdateData:tempString]; } } -(void) insertDatabase { NSError *error; NSString *textFile = [NSStringstringWithContentsOfFile:[[NSBundlemainBundle]pathForResource:@"schema.sqlite.data.sql"ofType:nil]encoding:NSUTF8StringEncodingerror:&error]; if (textFile ==nil) { NSLog(@"Error reading text file. %@", [errorlocalizedFailureReason]); } NSArray *row = [textFilecomponentsSeparatedByString:@";"]; NSInteger count = [rowcount]; SqliteHelp *t = [SqliteHelpnew]; for (int i=0; i<count; i++) { NSString *tempString = [NSStringstringWithFormat:@"%@;",row[i]]; NSLog(@"%@",tempString); [tinsertOrUpdateData:tempString]; } } @end
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。