在客户端软件开发过程中,基本都会涉及到数据库的开发。QT支持的数据库也有好几种(QSQLITE, QODBC, QODBC3, QPSQL, QPSQL7),SQLite就是其中之一,但这个 SQLite 是官方提供的开源版本,没有加密功能的。如果对于数据保密性有要求的,那么就要考虑对数据库或者数据本身进行加密了。最好的选择或许是对数据库本身进行加密(既不会暴露表结构,也不会暴露数据细节),那么如何对sqlite3数据库进行加密?本文将逐一进行剖析。
一、下载插件
https://github.com/devbean/QtCipherSqlitePlugin
https://gitee.com/mirrors/QtCipherSqlitePlugin
二、QtCipherSqlitePlugin的编译
QtCipherSqlitePlugin工程包含三个项目:demo、sqlitecipher、test_plugin。其中sqlitecipher是插件,另外两个都是示例程序。使用qtcreator打开QtCipherSqlitePlugin.pro文件,再选择项目的编译器,在debug模式下编译。编译完成后的dll文件位于:sqlitecipher\plugins\sqldrivers\sqlitecipher.dll
三、QtCipherSqlitePlugin的使用
- 找到sqlitecipher/plugins/sqldrivers/sqlitecipher.dll文件,将其拷贝到qt目录下 C:\Qt\5.14.2\mingw73_64\plugins\sqldrivers。
- 检查插件是否成功加载
qDebug() << QSqlDatabase::drivers();
- 如果输出的内容包含SQLITECIPHER,则表示已被成功加载。例如我输出的是:“QSQLITE”, “QODBC”, “QODBC3”, “QPSQL”, “QPSQL7”, “SQLITECIPHER”
- 支持的加密方式:aes128cbc、aes256cbc、chacha20、sqlcipher、rc4
四、示例代码
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
Q_UNUSED(app)
qDebug() << QSqlDatabase::drivers();
Q_ASSERT(QSqlDatabase::isDriverAvailable("QSQLITE")); // from Qt
Q_ASSERT(QSqlDatabase::isDriverAvailable("SQLITECIPHER")); // from our plugin
//
QSqlDatabase conn = QSqlDatabase::addDatabase("SQLITECIPHER");
conn.setDatabaseName("test.db");
#if 0//将原本没有加密的数据库文件进行加密(只需要执行一次)
conn.setPassword("test");
QString options = "QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096; QSQLITE_CREATE_KEY";
conn.setConnectOptions(options);
bool ok = conn.open();
qDebug() << "open: " << ok << "\nisOpenError:" << conn.isOpenError() << "\nlastError:" << conn.lastError();
#endif
#if 0//删除数据库密码(QSQLITE_REMOVE_KEY or QSQLITE_UPDATE_KEY=)
conn.setPassword("test");
QString options = "QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096; QSQLITE_REMOVE_KEY";
conn.setConnectOptions(options);
bool ok = conn.open();
qDebug() << "open: " << ok << "\nisOpenError:" << conn.isOpenError() << "\nlastError:" << conn.lastError();
#endif
#if 1//修改数据库密码
conn.setPassword("test");
QString options = "QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096; QSQLITE_UPDATE_KEY=qqqq";
conn.setConnectOptions(options);
bool ok = conn.open();
qDebug() << "open: " << ok << "\nisOpenError:" << conn.isOpenError() << "\nlastError:" << conn.lastError();
#endif
conn.close();
return 0;
}
五、查看加密后的数据库
如何使用外部工具查看加密后的数据库,这里介绍一款软件 QSliteStudio