This is not typically a question where to find a step-by-step guide, but rather the guide itself.
My intention with this post is to give others a hint, who have the same problems in compiling the driver-plugin as I just had recently.
How to build the Qt-SQL-driver-plugin 'QSQLCIPHER' for SQLite-DB with SQLCipher-extension using the Windows/MinGW-platform:
Qt 5.4.0 for Windows/MinGW
C:\Qt\Qt5.4.0
OpenSSL for Windows
C:\OpenSSL-Win32
C:\Windows\SysWOW64
)MinGW - Minimalist GNU for Windows
C:\MinGW
C:\MinGW
C:\MinGW
to the Qt-MinGW-directory C:\Qt\Qt5.4.0\Tools\mingw491_32
Create file 'fstab' in C:\Qt\Qt5.4.0\Tools\mingw491_32\msys\1.0\etc
Insert content as follows:
#Win32_Path Mount_Point
C:/Qt/Qt5.4.0/Tools/mingw491_32 /mingw
C:/Qt/Qt5.4.0/5.4 /qt
C:/ /c
zlib-Library
C:\Qt\Qt5.4.0\Tools\mingw491_32\msys\1.0\bin
SQLCipher
C:\temp\sqlcipher-master
C:\OpenSSL-Win32\bin\libeay32.dll
to C:\temp\sqlcipher-master
C:\OpenSSL-Win32\lib\libeay32.lib
to C:\temp\sqlcipher-master
Build SQLCipher.exe
Execute 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
Save the executable SQLite/SQLCipher-database e.g. to C:\sqlcipher
C:\temp\sqlcipher-master\dist\bin\sqlcipher.exe
to C:\sqlcipher
.C:\temp\sqlcipher-master\sqlite3.dll
to C:\sqlcipher
.Build Qt-QSQLCIPHER-driver-plugin
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\plugins\sqldrivers\sqlcipher
Create the following three files within the new directory:
File 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"
File 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)
File 3: sqlcipher.json
{
"Keys": [ "QSQLCIPHER" ]
}
C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlite
to C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlcipher
Customize file C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\sql\drivers\sqlcipher\qsql_sqlite.pri
The content of the file shall be like:
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
}
Create file 'sqlcipher.pri' in directory C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty
with following content:
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/*
Create and fill C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\3rdparty\sqlcipher
Create the two directories:
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
Copy the following files to 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
Copy the following files/directories to 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
The directory now consists of the following files and directories:
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
Compile the QSQLCIPHER-driver-plugin for Qt:
C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\Qt5.4.0\5.4\mingw491_32\bin\qtenv2.bat
Execute the following commands:
cd C:\Qt\Qt5.4.0\5.4\Src\qtbase\src\pluins\sqldrivers\sqlcipher
qmake
mingw32-make
This builds the QSQLCIPHER-driver-plugin within the following directory:
C:\QT\QT5.4.0\5.4\SRC\QTBASE\PLUGINS\SQLDRIVERS
libqsqlcipher.a
libqsqlcipherd.a
qsqlcipher.dll
qsqlcipherd.dll
C:\Qt\Qt5.4.0\5.4\mingw491_32\plugins\sqldrivers
.Create a new encrypted SQLite/SQLCipher-database
Create new SQLite-Plaintext-database 'plaintext.db' with a test table and some test data
Change directory to C:\sqlcipher
, which contains 'sqlcipher.exe' and 'sqlite3.dll' (see above).
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
C:\sqlcipher\plaintext.db
using a standard text-editor:Encrypting the plaintext-database
This will create the database C:\sqlcipher\encrypted.db
using the key '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
C:\sqlcipher\encrypted.db
using a standard text-editor:Usage of the SQLite-database with SQLCipher-extension and access via Qt
Project file
QT += core sql
QT -= gui
TARGET = qsqlcipher
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
Test-program '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;
}
Compile and execute
("QSQLCIPHER", "QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7")
id= "1" , name= "Bob"
id= "2" , name= "Charlie"
id= "3" , name= "Daphne"
id= "4" , name= "dummy"
When delivering a Qt-program do not forget the Qt-libraries, the platforms-libraries, SQL-driver-plugin 'qsqlcipher.dll' and the OpenSSL-library 'libeay32.dll'.
Example for the test program above:
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
Caution: The test program contains the key:
...
q.exec("PRAGMA key = 'testkey';");
...
This key string in the binary file of the test program can easiliy be read using a hex-editor, which is, to my opinion, a lack in security:
...
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
...
For approaches how to solve this problem, ask the search engine of your own choice. ;-)
E.g. search for: hide string in executable