BlueRoseNote/07-Other/Qt/为Qt中的SQLite添加密码并加密.md
2023-06-29 11:55:02 +08:00

70 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 前言
因为Sqlite的源代码中只提供了Sqlite3_key()的接口没有实现。所以Qt中的Sqlite没有密码功能。于是我找了一下资料并且总结一下思路。现成的方法在最后。
## SQLite历代版本与下载
所有ReleaseTag:https://www.sqlite.org/cgi/src/taglist
SQLite不提供明确的下载地址所以地址需要开发者去猜……也就是通过最新的地址以及你所需要的版本号去推
例如:
- sqlite-amalgamation-3240000https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip
- sqlite-dll-win32-x86-3240000.ziphttps://www.sqlite.org/2018/sqlite-dll-win32-x86-3240000.zip
- sqlite-dll-win64-x64-3240000.ziphttps://www.sqlite.org/2018/sqlite-dll-win64-x64-3240000.zip
- sqlite-amalgamation-3270200.ziphttps://www.sqlite.org/2019/sqlite-amalgamation-3270200.zip
- sqlite-dll-win64-x64-3270200.ziphttps://www.sqlite.org/2019/sqlite-dll-win64-x64-3270200.zip
注意:
- 年份
- 版本号的小数点位在百位上
## 解决思路与大致过程
编写一个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并且载入时进行判断
- QtCipherSqlitePlugin地址
https://github.com/devbean/QtCipherSqlitePlugin
- 编译方法https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-compile
- 使用方法https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-use
## 参考资料
- https://www.devbean.net/2012/07/qt-sqlite-plugin-with-encryption/
- https://www.cnblogs.com/WushiShengFei/p/9707244.html