SQliteCipher 数据库加密实践

目录

1、github上获取源码,编译

2、将生成的dll其拷贝到QT中对应目录中

3、VS中创建Qt工程,引用SQL

4、补全动态库

5、使用加密数据库

6、多数据库操作

6.1 同时打开多数据库

6.2 获取指定数据库

6.3 附着数据库attach

6.4 操作表

6.5 查询结果

6.6 关闭数据库

7、总结

8、参考

9、源码参考地址

​​​​​​

1、github上获取源码,编译

地址:https://github.com/devbean/QtCipherSqlitePlugin

官方说明:https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-use

压缩包:QtCipherSqlitePlugin-develop.zip

编译时,我的VS2015、Qt5.11.0,在sqlitecipher.cpp中,593行处异常;

SQliteCipher 数据库加密实践

成功后:

SQliteCipher 数据库加密实践

SQliteCipher 数据库加密实践

2、将生成的dll其拷贝到QT中对应目录中

注意:release和debug版不通用!

SQliteCipher 数据库加密实践

3、VS中创建Qt工程,引用SQL

SQliteCipher 数据库加密实践

验证是否可用:

qDebug() << QSqlDatabase::drivers();

SQliteCipher 数据库加密实践

4、补全动态库

创建_files.bat文件,运行。

D:\ProgramTools\Qt\5.11.0\msvc2015\bin\windeployqt.exe SqliteEncrypt.exe -qml
pause

SQliteCipher 数据库加密实践

注意:新项目可能不会遗漏sqldrivers中的sqlitecipher.dll,但对已有项目非常有可能忘记,我在这生生卡了大半天,qDebug输出的driver中就是没有SQLITECIPHER!!!对比工程配置啥都一样,Demo也没错,最后发现是这个问题,气死!另,推荐文件比较神器:Beyond Compare。

SQliteCipher 数据库加密实践

SQliteCipher 数据库加密实践

5、使用加密数据库

加密后的数据库操作与未加密的基本都一样,只是在打开的时候不同,把驱动QSQLITE换成SQLITECIPHER。

//db = QSqlDatabase::addDatabase("QSQLITE");
db = QSqlDatabase::addDatabase("SQLITECIPHER");
db.setDatabaseName(db_name);//数据库文件全路径
db.setPassword("123456");//密码
db.setConnectOptions("QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096");//连接配置
if (!db.open())
    qDebug() << "Can not open connection: " << db.lastError();

数据库的加密方式有多种,我用的是:sqlcipher ,其他还有aes128cbc、aes256cbc、chacha20。这段代码是从官方demo中摘出来的。

SQliteCipher 数据库加密实践

使用工具 SQLiteStudio打开数据库:

SQliteCipher 数据库加密实践

SQliteCipher 数据库加密实践

到这里常规使用就应该没问题了。

6、多数据库操作

我处理项目中的数据库较多,有的还需要attach,又踩了一些坑。

6.1 同时打开多数据库

bool SqliteEncrypt::OpenDB(QString db_name, QString alias)
{
    if (!QSqlDatabase::contains(db_name))
    {//打开数据库,注意带上数据库连接标识alias,用于同时打开多个数据库用,非数据库名

        db = QSqlDatabase::addDatabase("SQLITECIPHER", alias); 
        db.setDatabaseName(db_name);//数据库文件全路径
        db.setPassword("123456");//密码
        db.setConnectOptions("QSQLITE_USE_CIPHER=sqlcipher; SQLCIPHER_LEGACY=1; SQLCIPHER_LEGACY_PAGE_SIZE=4096");//连接配置

        if (!db.open()) {
            qDebug() << "Can not open connection: " << db.lastError();
            return false;
        }
    }

    return true;
}

6.2 获取指定数据库

注意:用alias获取。

QSqlDatabase db = QSqlDatabase::database(db_alias);

6.3 附着数据库attach

这里有几个坑,在SQL编辑器里验证语句正确,但在代码中总是失败。

1、用旧数据库QSQLITE_CREATE_KEY创建密码后,attach总出错,错误是Error: QSqlError(“26”, “Unable to fetch row”, “file is not a database”);

2、attach语句加上KEY=密码,同样报Error: QSqlError(“26”, “Unable to fetch row”, “file is not a database”);

3、db_attach用相对路径,加上KEY=密码,返回值会为true,但实际没成功,在查询时报Error: QSqlError(“1”, “Unable to execute statement”, “no such table: DB2.test”)。

解决方法

1、一定要重新创建带密码的新库!!然后再把旧库中的表复制进去就成功了。

2、Attach语句中不带KEY,表示用和主数据库相同的密码(或空密码)。

bool SqliteEncrypt::AttachDB(QString db_alias, QString db_attach, QString _alias)
{
&#xA0;&#xA0;&#xA0; bool res = false;
&#xA0;&#xA0;&#xA0; QString sql = "ATTACH DATABASE '" + db_attach + "' AS " + _alias;// +" KEY '123456'; ";

&#xA0;&#xA0;&#xA0; QSqlQuery query(db.database(db_alias));
&#xA0;&#xA0;&#xA0; res = query.prepare(sql);
&#xA0;&#xA0;&#xA0; if (!res) qDebug() << "Error:" << query.lastError();
&#xA0;&#xA0;&#xA0; res = query.exec();
&#xA0;&#xA0;&#xA0; if (!res) qDebug() << "Error:" << query.lastError();

    return res&#xFF1B;
}

因本人水平有限,深层原因未能明了,望知道原因的朋友留言告知。

6.4 操作表

从DB1里查询DB2

bool SqliteEncrypt::SelectDB(QString db_alias, QString sql)
{
    sql = "Select * from DB2.test";

    bool res = false;

    db = QSqlDatabase::database(db_alias);
    QSqlQuery query1(db);

    res = query1.prepare(sql);
    if (!res) qDebug() << "Error:" << query1.lastError();
    res = query1.exec();
    if (!res) qDebug() << "Error:" << query1.lastError();

    int nCount = query1.record().count();//获取查询记录的字段数   

    return res;
}

6.5 查询结果

SQliteCipher 数据库加密实践

6.6 关闭数据库

数据库打开后,文件被占用,需关闭才能做剪切、删除等操作。

void SqliteEncrypt::CloseDB(QString db_alias)
{
    if (QSqlDatabase::contains(db_alias)) {
        db.database(db_alias);
        db.close();
        db.removeDatabase(db_alias);
    }
}

7、总结

SQliteCipher没什么难点,把自己踩过的坑记录下来,能帮到大家就更好了。这一套操作整下来 真是把自己气坏了,基本功太不扎实,往后的路还很长,需不断学习,提升自己。与各位朋友共勉。

8、参考

SQLite Encryption Extension: Documentation

How to use · devbean/QtCipherSqlitePlugin Wiki · GitHub

编译出带加密功能的 SQLite Qt 插件并用SQLiteStudio进行查看_斧冰-CSDN博客

为Qt中的SQLite添加密码并加密 – BlueRose’s Blog

使用SQLite附加(ATTACH)数据库时,需要注意数据文件编码的问题_weixin_33692284的博客-CSDN博客

9、源码参考地址

Qt中SQlite数据库加密SqliteCipher实例-互联网文档类资源-CSDN下载

Original: https://blog.csdn.net/woguanni/article/details/120524602
Author: woguanni
Title: SQliteCipher 数据库加密实践

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815842/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球