zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    ", 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
    ", 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 	 	", sqlite3_column_text(pStmt, i));
            }
            printf("
    ");
            c = sqlite3_step(pStmt);
        }
        
        if (c != SQLITE_DONE)
            throw sqlite3_errmsg(pDb);
    
        c = sqlite3_finalize(pStmt);
        if (c != SQLITE_OK)
            throw sqlite3_errmsg(pDb);
    }
  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/luweimy/p/4214663.html
Copyright © 2011-2022 走看看