BlueRose
文章97
标签28
分类7
为Qt中的SQLite添加密码并加密

为Qt中的SQLite添加密码并加密

前言

因为Sqlite的源代码中只提供了Sqlite3_key()的接口,没有实现。所以Qt中的Sqlite没有密码功能。于是我找了一下资料,,并且总结一下思路。现成的方法在最后。

SQLite历代版本与下载

所有ReleaseTag:https://www.sqlite.org/cgi/src/taglist

SQLite不提供明确的下载地址,所以地址需要开发者去猜……,也就是通过最新的地址以及你所需要的版本号去推:

例如:

注意:

  • 年份
  • 版本号的小数点位在百位上

解决思路与大致过程

编写一个QSQLDriver Plugins,并且实现Sqlite3_key()。

大致步骤

  • 在QtCreator中文件-新建文件或者项目-Library-c++Library来创建QSQLDriver Plugins(库类型选择Qt Plugin)。
  • 下载Qt源代码,并将\qtbase\src\plugins\sqldrivers\sqlite下的qsql_sqlite_p.h与qsql_sqlite.cpp文件复制到新建的插件目录下。
  • 修改2个文件中类名与创建插件的类名一致。并且修改open()函数(具体的请看参考资料)。
  • 下载sqlite源代码,并且实现Sqlite3_key(),注意该函数被宏设置为不编译。可以通过在项目中设置来解决也可以在头文件中直接设置宏为1来解决。
  • Sqlite3_key()的实现方法可以参考wxsqlite3或CipherSqlite。

现成的解决方法

国人编写的插件:QtCipherSqlitePlugin。经测试5.14.2 MSVC2017 x64可以使用。使用起来很方便,直接用Qt打开sqlitecipher文件夹中的工程,直接切成release模式编译即可。

作者推荐的方法是将编译出lib与dll都放入源代码中的,不过我个人还是喜欢使用在项目中直接加载Plugin的方式来实现。这样可以方便后续的项目迁移与后续维护。大致代码如下:

QPluginLoader driverload(qApp->applicationDirPath()+"/plugin/sqldrivers/sqlitecipher.dll");
    if(driverload.load())
    {
        QSqlDriverPlugin *plugin=qobject_cast<QSqlDriverPlugin*>(driverload.instance());
        if(plugin)
        {
            QSqlDriver *driver=plugin->create("SQLITECIPHER");
            QSqlDatabase db;
                       db=QSqlDatabase::addDatabase(driver);
                       db.setDatabaseName("mydatabase.db");
                       db.setPassword("123456");
                       if(db.open())
                       {
                           QSqlQuery qry(db);
                           qry.exec("create table t_trade(order_id varchar(100))");
                           qry.exec("insert into t_trade(order_id) values('10001')");
                           qry.exec("insert into t_trade(order_id) values('10002')");
                           qry.exec("select * from t_trade");
                           while(qry.next())
                           {
                               qDebug()<<qry.value(0).toString();
                           }
                       }
        }
    }

PS.debug与release的dll是不通用的,所以需要编译两份dll,并且载入时进行判断!

参考资料