Woo*_*ker 5 sqlite encryption qt mingw sqlcipher
这通常不是一个问题,在哪里可以找到分步指南,而是指导本身.
我对这篇文章的意图是给别人一个提示,他在编译驱动程序插件方面遇到的问题和我最近的问题一样.
如何使用Windows / MinGW平台为具有SQLCipher扩展名的SQLite-DB构建Qt-SQL-driver-plugin'QSQLCIPHER':
适用于Windows / MinGW的Qt 5.4.0
C:\Qt\Qt5.4.0适用于Windows的OpenSSL
C:\OpenSSL-Win32C:\Windows\SysWOW64)MinGW-Windows的极简GNU
C:\MinGWC:\MinGWC:\MinGW到Qt-MinGW目录C:\Qt\Qt5.4.0\Tools\mingw491_32在以下位置创建文件“ fstab” C:\Qt\Qt5.4.0\Tools\mingw491_32\msys\1.0\etc
插入内容如下:
#Win32_Path Mount_Point
C:/Qt/Qt5.4.0/Tools/mingw491_32 /mingw
C:/Qt/Qt5.4.0/5.4 /qt
C:/ /c
Run Code Online (Sandbox Code Playgroud)zlib-库
C:\Qt\Qt5.4.0\Tools\mingw491_32\msys\1.0\binSQL密码
C:\temp\sqlcipher-masterC:\OpenSSL-Win32\bin\libeay32.dll到C:\temp\sqlcipher-masterC:\OpenSSL-Win32\lib\libeay32.lib到C:\temp\sqlcipher-master生成SQLCipher.exe
执行MSYS: C:\Qt\Qt5.4.0\Tools\mingw491_32\msys\1.0\msys.bat
$ cd /c/temp/sqlcipher-master
$ ./configure --prefix=$(pwd)/dist --with-crypto-lib=none --disable-tcl CFLAGS="-DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -I/c/openssl-win32/include /c/temp/sqlcipher-master/libeay32.dll -L/c/temp/sqlcipher-master/ -static-libgcc" LDFLAGS="-leay32"
$ make clean
$ make sqlite3.c
$ make
$ make dll
$ make install
Run Code Online (Sandbox Code Playgroud)保存可执行的SQLite / SQLCipher数据库,例如 C:\sqlcipher
C:\temp\sqlcipher-master\dist\bin\sqlcipher.exe到C:\sqlcipher。C:\temp\sqlcipher-master\sqlite3.dll到C:\sqlcipher。构建Qt-QSQLCIPHER-driver-plugin
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\plugins\sqldrivers\sqlcipher在新目录中创建以下三个文件:
文件1:smain.cpp:
#include <qsqldriverplugin.h>
#include <qstringlist.h>
#include "../../../../src/sql/drivers/sqlite/qsql_sqlite_p.h" // There was a missing " at the end of this line
QT_BEGIN_NAMESPACE
class QSQLcipherDriverPlugin : public QSqlDriverPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QSqlDriverFactoryInterface" FILE "sqlcipher.json")
public:
QSQLcipherDriverPlugin();
QSqlDriver* create(const QString &);
};
QSQLcipherDriverPlugin::QSQLcipherDriverPlugin()
: QSqlDriverPlugin()
{
}
QSqlDriver* QSQLcipherDriverPlugin::create(const QString &name)
{
if (name == QLatin1String("QSQLCIPHER")) {
QSQLiteDriver* driver = new QSQLiteDriver();
return driver;
}
return 0;
}
QT_END_NAMESPACE
#include "smain.moc"
Run Code Online (Sandbox Code Playgroud)文件2:sqlcipher.pro
TARGET = qsqlcipher
SOURCES = smain.cpp
OTHER_FILES += sqlcipher.json
include(../../../sql/drivers/sqlcipher/qsql_sqlite.pri)
wince*: DEFINES += HAVE_LOCALTIME_S=0
PLUGIN_CLASS_NAME = QSQLcipherDriverPlugin
include(../qsqldriverbase.pri)
Run Code Online (Sandbox Code Playgroud)文件3:sqlcipher.json
{
"Keys": [ "QSQLCIPHER" ]
}
Run Code Online (Sandbox Code Playgroud)C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlite
到C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlcipher自定义文件文件C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlcipher\qsql_sqlite.pri
的内容应类似于:
HEADERS += $$PWD/qsql_sqlite_p.h
SOURCES += $$PWD/qsql_sqlite.cpp
!system-sqlite:!contains(LIBS, .*sqlite3.*) {
include($$PWD/../../../3rdparty/sqlcipher.pri) #<-- change path of sqlite.pri to sqlcipher.pri here !
} else {
LIBS += $$QT_LFLAGS_SQLITE
QMAKE_CXXFLAGS *= $$QT_CFLAGS_SQLITE
}
Run Code Online (Sandbox Code Playgroud)在目录中创建文件“ sqlcipher.pri”,C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty其内容如下:
CONFIG(release, debug|release):DEFINES *= NDEBUG
DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_RTREE SQLITE_HAS_CODEC
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
contains(QT_CONFIG, posix_fallocate):DEFINES += HAVE_POSIX_FALLOCATE=1
winrt: DEFINES += SQLITE_OS_WINRT
winphone: DEFINES += SQLITE_WIN32_FILEMAPPING_API=1
qnx: DEFINES += _QNX_SOURCE
INCLUDEPATH += $$PWD/sqlcipher c:/openssl-win32/include
SOURCES += $$PWD/sqlcipher/sqlite3.c
LIBS += -L$$PWD/sqlcipher/lib -lsqlcipher -leay32 -lsqlite3
TR_EXCLUDE += $$PWD/*
Run Code Online (Sandbox Code Playgroud)创建并填写 C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher
创建两个目录:
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher\lib
Run Code Online (Sandbox Code Playgroud)将以下文件复制到C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher:
C:\temp\sqlcipher-master\shell.c
C:\temp\sqlcipher-master\sqlite3.c
C:\temp\sqlcipher-master\sqlite3.h
C:\temp\sqlcipher-master\sqlite3ext.h
Run Code Online (Sandbox Code Playgroud)将以下文件/目录复制到C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher\lib:
C:\temp\sqlcipher-master\dist\lib
C:\temp\sqlcipher-master\sqlite3.dll
C:\OpenSSL-Win32\bin\libeay32.dll
Run Code Online (Sandbox Code Playgroud)该目录现在包含以下文件和目录:
C:\QT\QT5.4.0\5.4\SRC\QTBASE\SRC\3RDPARTY\SQLCIPHER
| shell.c
| sqlite3.c
| sqlite3.h
| sqlite3ext.h
|
\---lib
| libeay32.dll
| libsqlcipher.a
| libsqlcipher.la
| sqlite3.dll
|
\---pkgconfig
sqlcipher.pc
Run Code Online (Sandbox Code Playgroud)为Qt编译QSQLCIPHER-driver-plugin:
C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\Qt5.4.0\5.4\mingw491_32\bin\qtenv2.bat执行以下命令:
cd C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\pluins\sqldrivers\sqlcipher
qmake
mingw32-make
Run Code Online (Sandbox Code Playgroud)这将在以下目录中构建QSQLCIPHER-driver-plugin:
C:\QT\QT5.4.0\5.4\SRC\QTBASE\PLUGINS\SQLDRIVERS
libqsqlcipher.a
libqsqlcipherd.a
qsqlcipher.dll
qsqlcipherd.dll
Run Code Online (Sandbox Code Playgroud)C:\Qt\Qt5.4.0\5.4\mingw491_32\plugins\sqldrivers。创建一个新的加密SQLite / SQLCipher数据库
使用测试表和一些测试数据创建新的SQLite-Plaintext-database'plaintext.db'
将目录更改为C:\sqlcipher,其中包含“ sqlcipher.exe”和“ sqlite3.dll”(请参见上文)。
C:\sqlcipher>sqlcpher.exe plaintext.db
SQLCipher version 3.8.6 2014-08-15 11:46:33
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table testtable (id integer, name text);
sqlite> insert into testtable (id,name) values(1,'Bob');
sqlite> insert into testtable (id,name) values(2,'Charlie');
sqlite> insert into testtable (id,name) values(3,'Daphne');
sqlite> select * from testtable;
1|Bob
2|Charlie
3|Daphne
sqlite> .exit
Run Code Online (Sandbox Code Playgroud)C:\sqlcipher\plaintext.db使用标准的文本编辑器打开:加密明文数据库
这将C:\sqlcipher\encrypted.db使用密钥“ testkey” 创建数据库。
C:\sqlcipher>sqlcipher.exe plaintext.db
SQLCipher version 3.8.6 2014-08-15 11:46:33
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'testkey';
sqlite> SELECT sqlcipher_export('encrypted');
sqlite> DETACH DATABASE encrypted;
sqlite> .exit
Run Code Online (Sandbox Code Playgroud)C:\sqlcipher\encrypted.db使用标准的文本编辑器打开:结合使用SQLite数据库和SQLCipher-extension和通过Qt访问
项目文件
QT += core sql
QT -= gui
TARGET = qsqlcipher
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
Run Code Online (Sandbox Code Playgroud)测试程序“ main.cpp”
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QString>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
qDebug() << QSqlDatabase::drivers();
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLCIPHER");
db.setDatabaseName("C:/sqlcipher/encrypted.db");
db.open();
QSqlQuery q;
q.exec("PRAGMA key = 'testkey';");
q.exec("insert into testtable (id,name) values(4,'dummy')");
q.exec("SELECT id,name anz FROM testtable");
while (q.next()) {
QString id = q.value(0).toString();
QString name = q.value(1).toString();
qDebug() << "id=" << id << ", name=" << name;
}
db.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)编译并执行
("QSQLCIPHER", "QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7")
id= "1" , name= "Bob"
id= "2" , name= "Charlie"
id= "3" , name= "Daphne"
id= "4" , name= "dummy"
Run Code Online (Sandbox Code Playgroud)提供Qt程序时,请不要忘记Qt库,平台库,SQL驱动程序插件'qsqlcipher.dll'和OpenSSL库'libeay32.dll'。
上面的测试程序示例:
C:\TEMP\QSQLCIPHER-TEST
| icudt53.dll
| icuin53.dll
| icuuc53.dll
| libeay32.dll
| libgcc_s_dw2-1.dll
| libstdc++-6.dll
| libwinpthread-1.dll
| qsqlcipher.exe
| Qt5Core.dll
| Qt5Sql.dll
|
+---platforms
| qminimal.dll
| qoffscreen.dll
| qwindows.dll
|
\---sqldrivers
qsqlcipher.dll
Run Code Online (Sandbox Code Playgroud)警告:测试程序包含以下密钥:
...
q.exec("PRAGMA key = 'testkey';");
...
Run Code Online (Sandbox Code Playgroud)
可以使用十六进制编辑器轻松读取测试程序的二进制文件中的此密钥字符串,我认为这是缺乏安全性的:
...
00002C90 70 68 65 72 2F 65 6E 63 72 79 70 74 65 64 2E 64 pher/encrypted.d
00002CA0 62 00 50 52 41 47 4D 41 20 6B 65 79 20 3D 20 27 b.PRAGMA key = '
00002CB0 74 65 73 74 6B 65 79 27 3B 00 00 00 69 6E 73 65 testkey';...inse
00002CC0 72 74 20 69 6E 74 6F 20 74 65 73 74 74 61 62 6C rt into testtabl
...
Run Code Online (Sandbox Code Playgroud)
有关如何解决此问题的方法,请询问您自己选择的搜索引擎。;-)
例如搜索:在可执行文件中隐藏字符串