💂 个人主页:pp不会算法^ v ^
 🤟 版权: 本文由【pp不会算法v】原创、在CSDN首发、需要转载请联系博主
 💬 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦
文章目录
- 简介
- 编译安装
- 使用
- 可视化工具查看
- 完结
简介
在客户端存储数据的时候很多情况都会使用sqlite,像微信这种主流软件在客户端储存数据也用到了sqlite,
 但是普通的sqlite是没有加密的也就是说别人可以直接打开那个.db文件查看存储的内容,
针对数据安全,有两种方案:
 一种就是将写入的数据加密,这样就算别人打开也是加密后的内容
 另一种就是对数据库本身加密,sqlite官方提供也一个加密版本但是那是商业收费的
 但是还是有两款开源的基于sqlite的加密数据库sqlitecipher和wxsqlite
 wxsqlite3是基于sqlitecipher的,
我下面介绍的这个qt插件就是基于wxsqlite的
 
编译安装
github链接:https://github.com/devbean/QtCipherSqlitePlugin.git
 不要用gitee上那个镜像,那个稍微有点问题(别问为什么我用过出了问题)
把代码拉取下来之后直接打开pro文件用mingw编译,编译完之后在生成目录下的
 plugins/sqldrivers/这个目录下生成如下图的三个库文件
 
 然后将下面这两个文件复制导对对应编译器的:D:\ITSoftWare\QT5.15.2\Qtbase\5.15.2\mingw81_64\plugins\sqldrivers(以我的为例我是用mingw81_64编译的,release和debug模式编译的都一样)中
 
 然后把下面这个.a文件放到对应编译器目录的lib目录下:D:\ITSoftWare\QT5.15.2\Qtbase\5.15.2\mingw81_64\lib(以我的为例)
 
使用
输出QSqlDatabase::drivers()看一看时候包含了 SQLITECIPHER,如果包含了那么证明安装成功了
 使用和qt的sqlite模块基本一致,
 只要在初始化数据库的时候添加一下密码就行了,
 db_ = QSqlDatabase::addDatabase(“SQLITECIPHER”, connectionName_);
 db_.setPassword(“123698745”);
示例代码:
#include <QtSql>
#include <QCoreApplication>
#include <QTemporaryDir>#ifndef QT_DEBUG
#error Must be built in debug mode!
#endif#ifdef Q_OS_IOS
#  include <QtPlugin>Q_IMPORT_PLUGIN(SqliteCipherDriverPlugin)
#endif#define CONNECTION_FAILED -1int main(int argc, char *argv[])
{QCoreApplication app(argc, argv);Q_UNUSED(app)qDebug() << QSqlDatabase::drivers();Q_ASSERT(QSqlDatabase::isDriverAvailable("QSQLITE")); // from QtQ_ASSERT(QSqlDatabase::isDriverAvailable("SQLITECIPHER")); // from our pluginQTemporaryDir tmp;Q_ASSERT(tmp.isValid());auto withDB = [&](const char *driver, auto fn) {QString path = QDir(tmp.path()).absoluteFilePath(QString(driver) + ".db");{QSqlDatabase db = QSqlDatabase::addDatabase(driver, "db");db.setDatabaseName(path);Q_ASSERT(db.open());fn(db);}QSqlDatabase::removeDatabase("db");};//    // QSQLITE
//    {
//        // Create a SQLite db
//        withDB("QSQLITE", [](auto db) {
//            db.exec("create table foo (bar integer)");
//            db.exec("insert into foo values (42)");
//        });//        // Check that we can read from the SQLite db
//        withDB("QSQLITE", [](auto db) {
//            QSqlQuery q = db.exec("select bar from foo");
//            Q_ASSERT(q.next());
//            Q_ASSERT(q.value(0).toInt() == 42);
//        });//        // Check that SQLite is not SQLCipher
//        withDB("QSQLITE", [](auto db) {
//            QSqlQuery q = db.exec("select sqlcipher_export()");
//            QString errmsg = q.lastError().databaseText();
//            Q_ASSERT(errmsg.startsWith("no such function"));
//        });
//    }//    // SQLITECIPHER
//    {
//        // Check that SQLiteCipher is not SQLite
//        withDB("SQLITECIPHER", [](auto db) {
//            QSqlQuery q = db.exec("select sqlcipher_export()");
//            QString errmsg = q.lastError().databaseText();
//            qDebug() << errmsg;
//            Q_ASSERT(errmsg.startsWith("wrong number of arguments"));
//        });//        // Create a SQLiteCipher db with a passphrase
//        withDB("SQLITECIPHER", [](auto db) {
//            db.exec("pragma key='foobar'");
//            db.exec("create table foo (bar integer)");
//            db.exec("insert into foo values (42)");
//        });//        // Check that we can't read from the SQLiteCipher db without the passphrase
//        withDB("SQLITECIPHER", [](auto db) {
//            QSqlQuery q = db.exec("select bar from foo");
//            Q_ASSERT(!q.next());
//        });//        // Check that we can read from the SQLiteCipher db with the passphrase
//        withDB("SQLITECIPHER", [](auto db) {
//            db.exec("pragma key='foobar'");
//            QSqlQuery q = db.exec("select bar from foo");
//            Q_ASSERT(q.next());
//            Q_ASSERT(q.value(0).toInt() == 42);
//        });
//    }QString dir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
//    QString DB_FILE_PATH = dir + "/test_chacha20.db";QString DB_FILE_PATH = dir + "/local.db";qDebug() << "DB File Path is:" << DB_FILE_PATH;QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");dbconn.setDatabaseName(DB_FILE_PATH); //localDB.db is already existing before running the applicationdbconn.setPassword("pass");dbconn.setConnectOptions("QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096; QSQLITE_CREATE_KEY");bool open = dbconn.open();qDebug() << "open: " << open;qDebug() << "isOpen(): " << dbconn.isOpen() << dbconn.isOpenError();qDebug() << "create_key: " << dbconn.lastError();if (!dbconn.isOpen()){qDebug() << "Connection failed: " << dbconn.lastError().driverText();exit(CONNECTION_FAILED);}QSqlQuery query;
//    query.exec("create table test (id int, name varchar)");
//    query.exec("insert into test values (1, 'AAA')");
//    query.exec("insert into test values (2, 'BBB')");
//    query.exec("insert into test values (3, 'CCC')");
//    query.exec("insert into test values (4, 'DDD')");
//    query.exec("insert into test values (5, 'EEE')");
//    query.exec("insert into test values (6, 'FFF')");
//    query.exec("insert into test values (7, 'GGG')");
//    query.exec("select * from test where name regexp '(a|A)$'");
//    if (query.next()) {
//        qDebug() << "Regexp result: " << query.value(0).toInt() << ": " << query.value(1).toString();
//    } else {
//        qDebug() << "This plugin does not support regexp.";
//    }
//    qDebug() << "----------" << endl;query.exec("select id, name from test");while (query.next()) {qDebug() << query.value(0).toInt() << ": " << query.value(1).toString();}
//    qDebug() << "----------" << endl;
//    query.exec("update mapping set name='ZZZ' where id=1");
//    query.exec("select id, name from mapping");
//    while (query.next()) {
//        qDebug() << query.value(0).toInt() << ": " << query.value(1).toString();
//    }
//    qDebug() << "----------" << endl;
//    query.exec("delete from mapping where id=4");
//    query.exec("select id, name from mapping");
//    while (query.next()) {
//        qDebug() << query.value(0).toInt() << ": " << query.value(1).toString();
//    }
//    query.exec("drop table mapping");dbconn.close();return 0;
}
可视化工具查看
由于数据库被加密了使用一般的数据库可视化工具例如Navicat查看不了,这里我们可以下载sqlitestudio这款工具,也是qt写的,安装好了之打开上述示例代码创建的数据库
 
完结
如果你觉得对你有帮助,那麻烦三连一下吧
qt/c++技术交流q群:287590944