用VS2015编译sqlcipher

简介

SQLite,是一款轻型的数据库,是遵照ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp创建的公有领域项目。它的设计目标是嵌入式的,并且目前已经在不少嵌入式产品中使用了它,它占用资源很是的低,在嵌入式设备中,可能只须要几百K的内存就够了。它可以支持Windows/Linux/Unix等等主流的操做系统,同时可以跟不少程序语言相结合,好比 Tcl、C#、PHP、Java等,还有ODBC接口,一样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来说,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2015年已经有15个年头,SQLite也迎来了一个版本 SQLite 3已经发布。
可是sqlite自己不对数据库文件进行加密,存储的文件能够明文查看,存作这必定的安全隐患。还好做者提供了几个接口可让sqlite支持数据加密。比较有名的就是SQLCipher。
SQLCipher是一个开源库,提供透明,安全的256位AES加密的SQLite数据库文件。
SQLCipher的社区版的源代码是一个BSD-风格的开源许可下发布,可是官方提供的二进制库须要购买。
引用官方的一张图,加密前和加密后的对比效果:
c++

摘自百度百科git

下载信息

sqlite官方网站
SQLite3.13.0源码
SQLite3.def文件
SQLCipher-3.1.0源码
OpenSSL-1.0.1g
ActivePerlgithub

步骤

安装Perl

从官网上下载ActivePerl并进行安装,我这里安装的是x64版本sql

编译openssl

  • 解压Openssl的源码,例如解压缩到openssl-1.0.1g目录下
  • 在openssl目录下新建build.bat批处理文件,内容以下
@echo off
@set OPTS=no-asm
@perl Configure VC-WIN32
@perl util\mkfiles.pl >MINFO
@perl util\mk1mf.pl %OPTS% debug VC-WIN32 >d32.mak
@perl util\mk1mf.pl %OPTS% VC-WIN32 >32.mak
@perl util\mkdef.pl 32 libeay > ms\libeay32.def
@perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
@nmake -f d32.mak
@nmake -f 32.mak
  • 打开须要编译的VC命令行工具进入openssl目录并运行build.bat开始编译,编译成功之后生成libeay32.lib、ssleay32.lib文件。我这里使用的是VS2015的命令行工具Developer Command Prompt for VS2015数据库

    编译sqlite3

  • 用VS2015新建一个空的win32 dll项目,例如我这里取名为sqlite3
  • 将下载到的sqlite压缩包文件解压缩到sqlite3项目文件夹内
  • 修改sqlite3.def文件,在文件的最后添加如下代码
sqlite3_key
sqlite3_rekey
  • 修改sqlite3.c文件,在文件的最开始部分添加如下代码
/*** START REQUIRED BY SQLCIPHER ***/
#define SQLITE_HAS_CODEC 1
#define SQLITE_ENABLE_RTREE 1
#define SQLITE_ENABLE_COLUMN_METADATA 1
#define SQLITE_TEMP_STORE 2
/*** END REQUIRED BY SQLCIPHER ***/
  • 继续修改sqlite3.c文件,在文件的最后添加如下代码
#include <sqlcipher/crypto.c>      /*** SQLCIPHER ADDITION ***/
#include <sqlcipher/crypto_cc.c>      /*** SQLCIPHER ADDITION ***/
#include <sqlcipher/crypto_impl.c> /*** SQLCIPHER ADDITION ***/
#include <sqlcipher/crypto_openssl.c> /*** SQLCIPHER ADDITION ***/
#include <sqlcipher/pager.c>       /*** SQLCIPHER ADDITION ***/
  • 仍是修改sqlite3.c文件,注释掉没必要要的头文件,新版本好像是注释掉的
/* #include "sqliteInt.h" */
/* #include "btreeInt.h" */

存放openssl的库

将编译成功的openssl库文件x86lib,内含libeay32.lib、ssleay32.lib,所有放到sqlite3目录下,设置工程目录连接这两个静态库安全

编译sqlite3

编译成功,便可生成对应的sqlite3.dll工具

使用示例代码

很少说了,直接上代码网站

#define SQLITE_HAS_CODEC
#include "sqlite3.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _DEBUG
#pragma comment(lib, "../Debug/sqlite3.lib")
#else
#pragma comment(lib, "../Release/sqlite3.lib")
#endif

#define ERROR(X)  /*{printf("[ERROR] iteration %d: ", i); printf X;fflush(stdout);}*/

static int callback(void *NotUsed, int argc, char **argv, char **azColName){  
    int i;  
    for(i=0; i<argc; i++){  
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");  
    }  
    printf("\n");  
    return 0;  
} 

int main(int argc, char **argv) {
    sqlite3 *db;
    const char *file= "sqlcipher.db";

    const char *key1 = "test123";
    char* key = (char *) key1;

    if (sqlite3_open(file, &db) == SQLITE_OK) {
        int  rc;

        if(db == NULL) {
            ERROR(("sqlite3_open reported OK, but db is null, retrying open %s\n", sqlite3_errmsg(db)))
        }

        if(sqlite3_key(db, key, strlen(key)) != SQLITE_OK) {
            ERROR(("error setting key %s\n", sqlite3_errmsg(db)))
                exit(1);
        }
        //SQLlite 操做代码...
        char* sqlstatement0 = "create table if not exists test(int id,varchar name);";  
        char* sqlstatement1 = "insert into test values(1,'hello');";  
        char* sqlstatement2 = "select * from test;";  
        char* zErrMsg = NULL;
        rc = sqlite3_exec(db, sqlstatement0, callback, 0, &zErrMsg);  
        if( rc!=SQLITE_OK ){  
//          printf("%s\n",argv[2]);  
            fprintf(stderr, "SQL error: %s\n", zErrMsg);  
            sqlite3_free(zErrMsg);  
            zErrMsg = NULL;
        } 
        rc = sqlite3_exec(db, sqlstatement1, callback, 0, &zErrMsg);  
        if( rc!=SQLITE_OK ){  
//          printf("%s\n",argv[2]);  
            fprintf(stderr, "SQL error: %s\n", zErrMsg);  
            sqlite3_free(zErrMsg);  
            zErrMsg = NULL;
        }  

        rc = sqlite3_exec(db, sqlstatement2, callback, 0, &zErrMsg);  
        if( rc!=SQLITE_OK ){  
            //          printf("%s\n",argv[2]);  
            fprintf(stderr, "SQL error: %s\n", zErrMsg);  
            sqlite3_free(zErrMsg);  
            zErrMsg = NULL;
        }  
        sqlite3_close(db);  
        system("pause");
    }
}
相关文章
相关标签/搜索