sqlite3的加解密全过程

目的

最近想用加密的sqlite3数据库,因为想把数据和数据结构都加密,让别人看不到一点信息,做到绝对的保密:

然后查sqlite3加密的资源,发现原生的Qt只支持sqlite3数据库,但其加密并未实现,这可是一个麻烦事了,怎么办?

分析了网上的各种信息,最终选择:插件模式。

为什么选择这种方式,这是最简单的,并且满足了要求,就这么简单。

而原生的方式,其实就是单独编译sqlite3的程序,但这个程序并未提供加密功能,因此又需要借助openssl实现加密功能,所以又得编译openssl库,编码openssl库,还得需要perl的支持,所以非常的麻烦,直接放弃掉这个原生的方法,直接用插件,这个方法最好了。

我们希望我们的数据库是能被加密的,只有我们用正确的密码才能连接上我们的数据库。加密之后就可以对数据安全作出一定的保障。

关于选择,一张图说明:

情况分析

wxSQLite3的介绍

wxSQLite3 是一个围绕 SQLite 3.x 数据库的 C++ 包装器,专门用于基于 wxWidgets 库的程序。

wxSQLite3 不会尝试隐藏底层数据库,相反,几乎支持当前 SQLite3 版本的所有特殊功能,例如创建用户定义的标量或聚合函数。

由于 SQLite 以 UTF-8 编码存储字符串,因此 wxSQLite3 方法提供了 wxStrings 和 UTF-8 字符串之间的自动转换。这最适合 wxWidgets 的 Unicode 构建。在 ANSI 构建中,当前的语言环境转换对象(wxConvCurrent)用于转换为 UTF-8 或从 UTF-8 转换。

如果使用外部管理工具修改数据库内容,则必须特别小心,因为并非所有这些工具都以 Unicode 或 UTF-8 模式运行。

从版本 1.7.0 开始,wxSQLite3 包含一个使用 AES 加密的基于密钥的 SQLite3 加密扩展。是否使用 128 位或 256 位 AES 加密的决定必须在编译时进行。

从版本 4.0.0 开始,加密扩展允许在运行时选择密码方案。目前支持以下加密方案:

AES 128 Bit CBC - No HMAC (wxSQLite3)

AES 256 Bit CBC - No HMAC (wxSQLite3)

ChaCha20 - Poly1305 HMAC (sqleet)

AES 256 Bit CBC - SHA1/SHA256/SHA512 HMAC (SQLCipher)

为什么选择插件的方式

sqlite官方带加密版本的是要收费的,这个时候就不得不推荐一个项目

QtCipherSqlitePlugin

该项目是一个QT的加密Sqlite数据库的插件,编译特别简单,直接使用QtCreator打开编译即可。

这是一个基于SQLite源代码和wxWidget中的wxSQLite3的cipher SQLite的Qt插件。

Qt是一个完整的开发框架,其工具旨在简化桌面、嵌入式和移动平台应用程序和用户界面的创建。您可以在https://www.qt.io上找到更多详细信息

SQLite是一个软件库,它实现了一个自包含、无服务器、零配置、支持事务的SQL数据库引擎。SQLite是全球部署最广泛的SQL数据库引擎。SQLite的源代码属于公有领域。您可以在http://www.sqlite.org/网站上找到更多详细信息。

wxSQLite3是围绕公共领域SQLite 3.x数据库的C++封装,专为基于wxWidgets库的程序设计。wxSQLite3包含一个SQLite的可选扩展,支持使用128位AES加密进行基于密钥的数据库文件加密。更多详细信息请访问http://utelle.github.io/wxsqlite3。wxSQLite3遵循wxWindows库许可协议发布。

你可以在这里找到如何编译这个插件。

你可以在这里找到如何使用这个插件。

此处显示更改内容。

生成QtCipherSqlite插件

源码:

https://github.com/devbean/QtCipherSqlitePlugin


放到Qt安装路径的plugins下面:

运行实例

cpp 复制代码
#pragma execution_character_set("utf-8")
#include <QtCore/QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QSqlError>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // 1. 初始化加密数据库
    QSqlDatabase db = QSqlDatabase::addDatabase("SQLITECIPHER");
    db.setDatabaseName("secure.db");
    db.setPassword("123456");
    db.setConnectOptions("QSQLITE_CREATE_CIPHER=sqlcipher;QSQLITE_USE_CIPHER=sqlcipher;QSQLITE_CIPHER=sqlcipher;SQLCIPHER_LEGACY=4");

    if (!db.open()) {
        qDebug() << "数据库打开失败:" << db.lastError();
        return -1;
    }

    // 2. 创建加密表
    QSqlQuery query(db);
    if (!query.exec("CREATE TABLE IF NOT EXISTS users ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "username TEXT UNIQUE NOT NULL,"
        "password TEXT NOT NULL)")) {
        qDebug() << "建表失败:" << query.lastError();
    }

    // 3. 删除数据
    if (!query.exec("DELETE FROM users WHERE username='admin' or username = 'test'")) {
        qDebug() << "删除失败:" << query.lastError();
    }

    // 4. 插入数据
    query.prepare("INSERT INTO users (username, password) VALUES (?, ?)");
    query.addBindValue("admin");
    query.addBindValue("123456");
    if (!query.exec()) {
        qDebug() << "插入失败:" << query.lastError();
    }
    query.prepare("INSERT INTO users (username, password) VALUES (?, ?)");
    query.addBindValue("test");
    query.addBindValue("123456");
    if (!query.exec()) {
        qDebug() << "插入失败:" << query.lastError();
    }

    // 5. 更新数据
    query.prepare("UPDATE users SET password=? WHERE username=?");
    query.addBindValue("654321");
    query.addBindValue("admin");
    if (!query.exec()) {
        qDebug() << "更新失败:" << query.lastError();
    }

    // 6. 查询数据
    if (query.exec("SELECT * FROM users")) {
        while (query.next()) {
            qDebug() << "ID:" << query.value(0).toString()
                << "用户名:" << query.value(1).toString()
                << "密码:" << query.value(2).toString();
        }
    }

    db.close();
    return a.exec();
}

运行情况:

与SQLiteStudio的连接情况:

不加密码,显示连接不上:

加密方式才成功:

wxSQLite3 - SQLite的轻量级封装库

wxSQLite3是围绕公共领域SQLite 3.x数据库的C++封装,专为基于wxWidgets库的程序设计。

wxSQLite3并不试图隐藏底层数据库,相反,它几乎支持当前SQLite3版本的全部特性,例如创建用户定义的标量函数或聚合函数。

由于SQLite以UTF-8编码存储字符串,因此wxSQLite3方法提供了wxStrings与UTF-8字符串之间的自动转换。这在wxWidgets的Unicode构建中效果最佳。在ANSI构建中,使用当前区域设置转换对象(wxConvCurrent)进行UTF-8的转换。如果使用外部管理工具来修改数据库内容,则必须特别小心,因为并非所有这些工具都以Unicode或UTF-8模式运行。

自1.7.0版本起,wxSQLite3包含了一个基于密钥的SQLite3加密扩展,该扩展使用AES加密。是否使用128位或256位AES加密的决定必须在编译时做出。从4.0.0版本开始,加密扩展允许在运行时选择密码方案。

目前支持以下加密方案:

AES 128位CBC - 无HMAC(wxSQLite3)

AES 256位CBC - 无HMAC(wxSQLite3)

ChaCha20 - Poly1305 HMAC(sqleet)(默认)(经验证默认的确是这个加密算法)

AES 256位CBC - SHA1/SHA256/SHA512 HMAC(SQLCipher版本1至4)

RC4 - 无HMAC(System.Data.SQLite)

Ascon 128 - Ascon标签(Ascon)(自4.9.8版本起)

AEGIS - AEGIS标签(AEGIS)(自4.10.0版本起)

总结

目的就是为了把整个数据库加密,关键选择哪一个库,选择了插件的库,插件使用非常的方便,知道用了QtCipherQqlitePlugin库,但这一个库是一个什么情况,需要大致了解,这一个插件库就是这样的情况:

相关推荐
计算机程序设计小李同学10 小时前
基于Python的在线零食购物商城系统的设计与实现
数据库·sqlite
openinstall全渠道统计18 小时前
开发者指南:广告投放系统搭建与前后端数据打通全流程
windows·git·oracle·eclipse·sqlite·github
Sammyyyyy2 天前
Django 6.0 发布,新增原生任务队列与 CSP 支持
数据库·后端·python·django·sqlite·servbay
赤龙绕月3 天前
SQLite NET
数据库·sqlite
透明的玻璃杯4 天前
sqlite数据库链接池二
数据库·oracle·sqlite
透明的玻璃杯4 天前
sqlite数据库连接池
jvm·数据库·sqlite
越甲八千5 天前
ASGI和AWSIG区别
数据库·python·sqlite
码农12138号5 天前
Bugku 2023 HackINI Virtual Shop 和 2023 HackINI Virtual Shop 2
web安全·sqlite·sql注入
飞Link6 天前
【Django】Django 调用外部 Python 程序的完整指南
后端·python·django·sqlite
姜太小白7 天前
【数据库】SQLite 时间加1天的方法总结
java·数据库·sqlite