sqlite3加密支持


sqlite3加密支持

sqlite3免費版並不支持加密,不過留有接口,有不少開源的加密實現,不過有的需要使用openssl配置略顯繁瑣,不過使用wxsqlite比較方便。

wxSqlite3

wxSqlite3是wxWidgets的擴展組件,對sqlite3的C API進行了封裝,並且實現了加解密功能。
目前支持兩種算法,AES128算法(默認)和AES256算法
wxSqlite在secure/src/sqlite3secure.c中引入了其他源文件,這樣你只用編譯sqlite3secure.c就可以了,但是這樣有時會比較麻煩。

sqlite3-secure

項目地址
我這里說的sqlite3-secure就是從wxSqlite3中提取的,只不過做了些修改,更加方便使用,直接添加到工程中就可以了。
而且使用起來仍然使用sqlite3的C API,沒有什么C++的封裝。

經過測試的系統:Mac OS X, iOS, Android

修改了什么?

  • 將不用添加到工程的C源文件后綴名改為ccode(要不然得屏蔽編譯這些文件,否則會出現符號重復的錯誤)
  • 默認啟用加密支持(添加啟用加密的宏)
  • 刪除了wxsqlite的C++封裝,只提供原生sqlite3-api
  • 刪除了shell.c(編譯shell命令工具sqlite的代碼)
  • 整理了目錄結構

加密解密API

// 解密或用於第一次加密
int sqlite3_key(sqlite3 *db, const void *zKey, int nKey);
// 重設密碼
int sqlite3_rekey(sqlite3 *db, const void *zKey, int nKey);

注意:

  • 第一次創建數據庫,使用sqlite3_key或者sqlite3_rekey都可以設置密碼
  • 必須在sqlite3_open成功之后,使用sqlite3_key進行解密
  • 要重新設置密碼(sqlite3_rekey),必須解密成功后才可以進行
  • 一般不重設密碼的話,只使用sqlite3_key就夠了

DEMO

//
//  main.cpp
//  sqlite3
//
//  Created by Luwei on 15/1/9.
//  Copyright (c) 2015年 Luwei. All rights reserved.
//

#include <iostream>

#include "sqlite3-secure/sqlite3.h"

void db_open(sqlite3 **ppDb, const std::string &path);
void db_close(sqlite3 *pDb);
void db_encrypt(sqlite3 *pDb, const std::string &password);

// DEMO
void db_createtable(sqlite3 *pDb);
void db_insert(sqlite3 *pDb);
void db_delete(sqlite3 *pDb);
void db_update(sqlite3 *pDb);
void db_select(sqlite3 *pDb);

int main()
{
    std::string path = "/Users/etime/Documents/db";
    std::string password = "hello,world";
    sqlite3 *pDb = nullptr;
    
    try {
        
        db_open(&pDb, path);
        db_encrypt(pDb, password);
        
        db_createtable(pDb);
        db_insert(pDb);
        db_delete(pDb);
        db_update(pDb);
        db_select(pDb);
        
        db_close(pDb);
    }
    catch (const char *what) {
        printf("[DB Error]: %s\n", what);
        sqlite3_close(pDb);
        return -1;
    }
    return 0;
}

void db_open(sqlite3 **ppDb, const std::string &path) {
    int c = SQLITE_OK;
    if (path.empty())
        c = sqlite3_open(":memory", ppDb);
    else
        c = sqlite3_open(path.c_str(), ppDb);
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(*ppDb);
}

void db_close(sqlite3 *pDb) {
    int c = sqlite3_close(pDb);
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
}

void db_encrypt(sqlite3 *pDb, const std::string &password) {
    int c = SQLITE_OK;
    if (password.empty())
        return;
    else
        c = sqlite3_key(pDb, password.c_str(), (int)password.length());
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
    
    // sqlite3_rekey()
}

void db_createtable(sqlite3 *pDb) {
    const char *sql =   "CREATE TABLE IF NOT EXISTS user"
                        "([id] INTEGER PRIMARY KEY, name TEXT)";
    
    int c = sqlite3_exec(pDb, sql, nullptr, nullptr, nullptr);
   
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
}

void db_insert(sqlite3 *pDb) {
    const char *sql = "INSERT INTO user values(NULL, 'luweimy')";

    int c = sqlite3_exec(pDb, sql, nullptr, nullptr, nullptr);
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
    
    int count = sqlite3_changes(pDb);
    printf("[DB Log]: <INSERT> %d item changes\n", count);
}

void db_delete(sqlite3 *pDb) {
    const char *sql = "DELETE FROM user WHERE id=2";
    
    int c = sqlite3_exec(pDb, sql, nullptr, nullptr, nullptr);
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
    
    int count = sqlite3_changes(pDb);
    printf("[DB Log]: <DELETE> %d item changes\n", count);
}

void db_update(sqlite3 *pDb) {
    const char *sql = "UPDATE user SET name=\"**luweimy**\" WHERE id=1";
    
    int c = sqlite3_exec(pDb, sql, nullptr, nullptr, nullptr);
    
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
    
    int count = sqlite3_changes(pDb);
    printf("[DB Log]: <UPADTE> %d item changes\n", count);
}

void db_select(sqlite3 *pDb) {
    const char *sql = "SELECT * FROM user";
    
    sqlite3_stmt *pStmt = nullptr;
    int c = sqlite3_prepare_v2(pDb, sql, (int)strlen(sql), &pStmt, nullptr);
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
    
    c = sqlite3_step(pStmt);
    if (c != SQLITE_ROW && c != SQLITE_DONE)
        throw sqlite3_errmsg(pDb);
    
    int colnum = sqlite3_column_count(pStmt);
    
    while (c == SQLITE_ROW) {
        for (int i = 0; i < colnum; i++) {
            printf("%s \t \t", sqlite3_column_text(pStmt, i));
        }
        printf("\n");
        c = sqlite3_step(pStmt);
    }
    
    if (c != SQLITE_DONE)
        throw sqlite3_errmsg(pDb);

    c = sqlite3_finalize(pStmt);
    if (c != SQLITE_OK)
        throw sqlite3_errmsg(pDb);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM