WCDB使用笔记

article/2025/10/9 9:17:51

本地数据加密

由于项目涉及到一些用户隐私数据的存储,所以需要对保存在客户端本地的数据进行加密,以防止用户隐私数据在设备被root的情况下出现泄漏。目前android的本地数据存储基本分为file,sharepreference和database,所以对数据的加密操作分为了两种:文件加密和文件内的数据加密。文件加密就是在打开该文件的时候需要获得正确的加密秘钥才能从该文件中读取数据或者写入数据到该文件中,这种方式相对简单。文件内数据加密就是打开文件时不需要解密,但是从文件中读取出来的数据是加密过的密文,需要对其进行解密才能识别和使用,同样在写入数据到文件的时候,也需要先将数据进行加密然后再写入到文件,这种方式相比第一种复杂一些,但是安全性更高,对数据保护的粒度更细。file和sharepreference使用上述两种方式实现的成本差异并不明显,database使用文件内数据比如列字段加密相比文件加密要更加复杂,所以database通常使用文件加密的方式来实现,比如有名的sqlcipher就是采用的这种方式,今天我们将要提到的wcdb也是采用的这种方式来保护数据的。

WCDB

wcdb是微信团队贡献的一个开源项目,是一个高效易用的数据库框架,并且支持多个平台。关于wcdb的更多介绍以及如何集成和使用WCDB请参考Tencent/wcdb,这里不再赘述。下面主要介绍一下我在将WCDB集成到原有项目(Android客户端)的过程中遇到的一些问题以及解决方案。因为我也是在使用WCDB的过程中不断查找资料,发现了一些别人没有遇到或者别人遇到了自己也遇到了但是没有清楚答案的问题,所以才想记录下来,以作备忘。

混淆

通常我们在引入一些知名的第三方库的时候,都需要在proguard中加入一些规则来屏蔽对该库的混淆,因为混淆可能会导致该库的部分功能异常,比如glide的项目介绍上就有如下说明:

image
但是我们在wcdb的项目上没有看到关于混淆这一块的介绍,刚开始我以为不需要,后来打了一个release包后发现wcdb运行报错,才知道这里还是有必要加一下的。内容如下:

-keep class com.tencent.wcdb.** {*;}

关于在proguard中如何加入第三方库的放混淆配置,可以使用以下方法。在android studio的project视图下的External Libraries中找到对应的库名字,比如wcdb,然后就可以看到这个库的完整包路径了。如下图:
image

加密已有数据

由于我的项目以前是使用android原生的sqlite储存数据,现在要迁移到wcdb上,就必须考虑到版本兼容的问题,当老版本升级到新版本后确保老版本上保存在本地的数据能无缝迁移到新版本上面来。那么对于已有数据的加密,wcdb的项目里面也提供了一个例子,我将核心代码贴出来:

File oldDbFile = mContext.getDatabasePath(OLD_DATABASE_NAME);
if (oldDbFile.exists()) {// SQLiteOpenHelper begins a transaction before calling onCreate().// We have to end the transaction before we can attach a new database.db.endTransaction();// Attach old database to the newly created, encrypted database.String sql = String.format("ATTACH DATABASE %s AS old KEY '';",DatabaseUtils.sqlEscapeString(oldDbFile.getPath()));db.execSQL(sql);// Export old database.db.beginTransaction();DatabaseUtils.stringForQuery(db, "SELECT sqlcipher_export('main', 'old');", null);db.setTransactionSuccessful();db.endTransaction();// Get old database version for later upgrading.int oldVersion = (int) DatabaseUtils.longForQuery(db, "PRAGMA old.user_version;", null);// Detach old database and enter a new transaction.db.execSQL("DETACH DATABASE old;");// Old database can be deleted now.oldDbFile.delete();
}

这里很多第一次使用wcdb的童鞋,如果没有细看这个例子中的代码会比较容易犯一个错误,就是将

DatabaseUtils.stringForQuery(db, "SELECT sqlcipher_export('main', 'old');", null);

不小心写成了

db.execSQL("SELECT sqlcipher_export('encrypted')");

然后发现怎么运行都会报异常。针对这个问题在项目里面还有一个issue:集成WCDB后希望能实现解密数据库 #36。我也遇到了,后面找了好久才发现是这里的问题,原因是wcdb的execSQL不支持select,但是原生的sqlite以及sqlcipher都是支持,所以在第一次用的时候就会觉得很奇怪,这条语句语法看上去完全没问题,运行就是行不通。

数据解密

有时为了方便定位问题,需要查看database的数据,如果是debug包可以直接联调查看,但如果是release包那么就必须手动导出db文件然后进行解密查看了。这里有两种方式解密:

  1. db文件拷贝到电脑上面,然后安装sqlcipher工具进行解密
  2. 在手机上使用wcdb sdk来解密

电脑端使用sqlcipher解密

首先在电脑端安装sqlcipher工具(链接:https://pan.baidu.com/s/1_yCOoqZJTersQ6KmkZb13w
提取码:jorr ),这里以windows为例,下载该工具后进入sqlcipher-3.0.1\bin\目录下,打开命令行工具,输入以下命令,如下图:

image

image
其中123456为加密秘钥,encrypt.db为加密的数据库文件,这里有几个地方需要注意:

  1. wcdb默认加密后的db文件的pagesize为4096,所以这里如果不设置cipher_page_size或者设置的值与你在使用wcdb加密时设置的pagesize一致的话,就会报错,这一点我网上找了很久都没发现有人提到,有的文章上设置的是1024,但是我试过就是不行,后来找了一个未加密的db文件看了下pagesize的值才发现不对。
  2. 在进行任何操作之前需要先使用pragma key=…来解密数据库,否则可能会报错“Error: file is encrypted or is not a database”,这里网上也有很多人跟我一样遇到。
  3. wcdb使用了sqlcipher来加密的,在加解密的时候必须使用一致的版本,比如我们使用sqlcipher3.x加密的,那么在解密的时候也必须使用3.x版本,否则就会解密失败。

有时在命令行里面解密和查看数据不太方便,我们可以将加密db中的数据导出到一个未加密的db中,首先我们在命令行工具中使用sqlcipher打开encrypt.db文件,然后输入如下命令:

pragma key='123456';
pragma cipher_page_size=4096;
attach database 'plaintext.db' as plaintext key '';
select sqlcipher_export('plaintext');
detach database plaintext;

其中123456为加密秘钥,palintext.db为解密后的db文件。执行完上述命令后,我们就会在当前目录下看到一个解密后的plaintext.db文件了,然后使用其他的数据库工具如sqlite expert等就可以正常打开查看里面的数据了。

wcdb sdk解密

使用wcdb sdk解密数据与之前提到的加密数据的过程是相识的,这里结合代码来详细说明。

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(getDataBase("encrypt.db"), "123456".getBytes(), null, null);
//将要生成的未加密db文件,这里可以根据自己的需要放在sd目录中方便导出查看
File plainDbFile = mContext.getDatabasePath("plaintext.db");
// Attach database 
String sql = String.format("ATTACH DATABASE %s AS plaintext KEY ';",DatabaseUtils.sqlEscapeString(plainDbFile.getPath()));
db.execSQL(sql);//导出加密数据库到未加密数据库中,sqlcipher_export这个方法有两个参数,第一个参数plaintext代表新生成的未加密数据库,第二个参数main代表已加密的数据库,也可以不使用第二个参数,那么默认将使用db关联的数据库导出到plaintext中。详细使用可以查看wcdb开源项目的android demo
db.beginTransaction();
DatabaseUtils.stringForQuery(db, "SELECT sqlcipher_export('plaintext', 'main');", null);
db.setTransactionSuccessful();
db.endTransaction();// Detach plaintext database
db.execSQL("DETACH DATABASE plaintext;");

这样我们就将一个加密数据库导出到了plaintext.db中。

总结

本文算是自己在项目中使用WCDB过程中一些使用心得和问题总结,WCDB在使用这一块其实还有更多高级的用法,这里并没有提到,后面有时间了再做详述。


http://chatgpt.dhexx.cn/article/YdntqsTu.shtml

相关文章

iOS开发通过微信学习WCDB(一)

最近通过对微信ipa包解压发现微信有使用WCDB这个开源库,搜索了一下了解到WCDB(WeChat Database)是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和Android。经过分析对比,个人感觉WC…

微信移动端数据库组件 WCDB 系列(三) — 解析 WINQ 原理

背景 高效、完整、易用是 WCDB 的基本原则。前几篇文章分享了 WCDB 的基本用法和修复工具,接下来将更深入地聊聊 WCDB 在易用性上的思考和实践。 对于各类客户端数据库,似乎都绕不开拼接字符串这一步。即便在 Realm 这样的 NoSQL 的数据库中&#xff0…

WCDB源码解析

源文链接:http://xiangwangfeng.com/2018/01/08/WCDB-源码解析 起因 最近开了个新项目,项目的主程童鞋引入了 WCDB 代替原先自制的 KeyValueStore 和 FMDB。问为何,答曰:好用,线程安全又高效。又问具体实现细节&#x…

IOS数据存储 之WCDB (二)WCDB.swift使用篇

IOS数据存储 之WCDB (二)WCDB.swift使用篇 1.WCDB.Swfit基础使用1.1 WCDB.Swfit 简介1.1.1 模型绑定1.1.2 创建数据库与表1.1.3 操作数据1.1.3.1 插入操作1.1.3.2 查找操作1.1.3.3 更新操作1.1.3.4 删除操作 1.2. 模型绑定1.2.1 Swift 模型绑定1.2.2 字段…

Android使用WCDB+Room 总结

最近项目有需要用到wcdb数据库,并且保证和IOS互通数据,在网上找很多相关资料,最后还是靠自己一点点摸索成功,现在做个总结。 一、在gradle 里加上 WCDB 相关的 room 组件 def room_version "2.3.0"// wcdb数据库和roo…

IOS数据存储 之WCDB (一)

IOS数据存储 之WCDB (一) 1. WCDB 简介1.1 使用WCDB框架3大优势1.2 WCDB 的一些基础概念1.2.1 类字段绑定(ORM)1.2.2 WINQ(WCDB语言集成查询)1.2.2.1 字段映射与运算符1.2.2.2 字段组合1.2.2.3 AllProperti…

iOS开发 数据存储之WCDB的介绍

一.介绍 WCDB是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS,macOS和Android 二.基本特性 易用,WCDB支持一句代码即可将数据取出并组合为object WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码ORM(Object Relational Ma…

开源微信小程序自助建站系统源码 含精美的多行业模板和搭建教程

分享一个微信小程序自助建站系统源码,含各行各业的小程序模板和搭建教程,可一键切换模板,自由DIY,搭建属于你自己的小程序。 特色功能一览: 11、支持创建多个小程序!(没有数量限制,后…

强大易用的开源建站工具Halo

最近无意间看到别人的博客外观非常美观,便萌生了偷师学艺的想法…所以就看到看了Halo这个开源的建站项目,其实使用起来非常简单,但是想要做一个类似的开源建站工具,谈何容易 访问官网 https://halo.run/ 使用docker部署 搜索镜像halo do…

14个免费好用的建站工具

有时候,我们想建立一个独立网站的时候,苦于自己技能不够,而迟迟没有行动,其实,我们真正的去构建一个独立网站的时候,我们并不需要多复杂的技术。我们也不一定要成为非常专业的程序员,因为现在&a…

推荐一款免费开源的建站系统 - AnqiCMS

安企内容管理系统(AnqiCMS),是一款使用 GoLang 开发的企业站内容管理系统,它部署简单,软件安全,界面优雅,小巧,执行速度飞快,使用 AnqiCMS 搭建的网站可以防止众多安全问题发生。AnqiCMS 的设计…

介绍一款开源、高性价比的在线教育建站系统

今天给大家介绍一款开源在线教育建站系统——edusoho,项目是用PHP开发,所以基本上会搭建php站点就可以完成本次的搭建。 先看看安装之后的登录界面。 去官网下载源码 笔者下载企培开源版:edusoho-ct-21.4.5.zip 系统说明 1.系统&#xff1…

国内好用的五款开源建站系统

推荐5款优秀的开源建站系统,都有免费版本,有需要可以去试试。蝉知 蝉知系统是一款开源的的企业营销自助建站系统。它专为企业营销设计,伪静态网址、关键词、语义化结构,内置流量统计。 蝉知功能全面,文章发布、会员管理、论坛评论、产品展示等,并内置商城系统,商品、订…

免费开源的建站程序大全,不会编程也可以自助搭建网站了哦

想建网站又不会编程的小伙伴有福啦,本期推荐一些开源的cms建站程序,不需要写后端的任何逻辑代码,轻轻松松就可以建立自己的网站了,当然,要想网站有自己的个性,模版还是需要自己写的,只需要会简单…

绝了!小说建站项目完整开源

超棒的开源小说文学建站 CMS 系统,作为面试项目有牌面儿! 编程导航开源仓库:https://github.com/liyupi/code-nav 大家好,我是鱼皮,今天给大家推荐一个优秀的开源 Java 全栈项目。 小说精品屋,是一套非常完…

最新首发自助建站系统源码,傻瓜式一键建站系统源码,高度开源支持专业在线自助建站服务平台软件

一佰互联,巅云门户自助建站系统v8建站平台版,历经3年不断打磨终于上线了。专业PS级大师级高端响应式智能建站平台软件,只为网络公司而生,采用国内知名开源php框架,Thinkphp6vue.js前端数据响应系统,实现了在线自助开通网站,企业站…

四大免费开源建站系统

原文:四大免费开源建站系统 - 知乎 第一: WordPress WordPress的主流客户是企业/个人的官网。一家公司不一定会在网上卖东西,但一定会需要一个官网。用WordPress做官网可谓是性价比最优选择。如果没有预算,你可以自己买几十美金的…

有哪些免费好用的开源建站程序/系统,推荐下?

我推荐WordPress建站程序,学习入门门槛很低,全世界近三分之一的网站都是采用wordpress,所以没有理由不去学习它。 我从一名小白变为wordpress建站老手,对比过很多建站程序,还是觉得wordpress能帮我节省时间和精力,让我…

开源自助建站系统源码完整源码+搭建教程 傻瓜式一键建站系统源码

一键傻瓜式自助建站系统源码,目前包含七百多套完整网站模板,全部都是响应式网站模板,傻瓜一键自助建站。开发组合PHPmysql,功能强大。 一键自助建站系统源码带安装教程,源码下载:春哥技术博客获取。自助建站…

五款开源免费的建站系统推荐

最近研究了下开源的建站系统,推荐5款国内的吧,都有免费版本,有需要可以去试试。 ECTouch ECTouch是一款开源免费的移动商城网店系统。能够帮助企业和个人快速构建手机移动商城并减少二次开发带来的成本。 ECTouch采用PHPMYSQL方式运行&…