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);
    }
  • 相关阅读:
    Mysql简单使用
    yum与rpm常用选项
    vim常用配置
    Python模块安装方式
    VirtualBox新建虚拟机常用配置
    Linux中单引号与双引号区别
    etc/profile /etc/bashrc ~/.bash_profile ~/.bashrc等配置文件区别
    virtualenv简单使用
    SqlDataSource学习笔记20091111:ConflictDetection属性
    TreeView学习笔记20091114:遍历树(叶子节点设置多选框)并设置展开级别
  • 原文地址:https://www.cnblogs.com/luweimy/p/4214663.html
Copyright © 2011-2022 走看看