微信 PC 端数据库为什么打不开:SQLCipher 与密钥推导

先说结论:微信的本地数据库是 SQLCipher 加密库,密钥不是固定常量,而是用「设备特征 + 账号标识」算出来的。所以同一份库在不同设备上能不能打开,答案是不一样的。

SQLCipher 是什么

它不是「把整个文件加密一遍」那么简单,而是把 SQLite 的每一个数据页加密,另外对文件头部、日志文件、索引也做处理。特性包括:

  • PBKDF2 派生密钥(默认 HMAC-SHA512,迭代数万次);
  • 每个库有独立的随机 salt,存在文件头附近;
  • 页大小、KDF 迭代次数、HMAC 算法都可以配,所以「同一个 SQLCipher」的不同版本互不兼容是常态;
  • 加密之后的文件头不是 SQLite format 3,这就是为什么常规工具直接报「不是数据库」。

密钥是怎么来的

这是关键,也是所有教程里最容易被含糊带过的部分。历史上(微信 6.x 时代)安卓端的密钥算法是:

key = md5(IMEI + uin).substring(0, 7)

其中 uin 是账号的数字 ID,IMEI 是设备标识。这个算法广为流传,因为它足够简单。但它同时也解释了另一件事:换设备、换账号、清空设备标识,密钥就变了。

后来的版本陆续加严:

  • 新版安卓取不到真实 IMEI(系统权限收紧),改用其他设备指纹;
  • 引入了账号维度的额外因子;
  • Windows 端的 MSG*.db 用的是 SQLCipher 4 的参数(PBKDF2-HMAC-SHA512、迭代 256000、salt 16 字节、页 4096),密钥来源同样和账号绑定。

这些细节每个大版本都可能变,所以任何「一把钥匙开所有库」的说法都不成立。

为什么换机后就打不开了

  1. 旧库是在旧设备上创建的,salt 和密钥都绑定当时的设备环境;
  2. 新设备上的微信生成的是新库,和旧库毫无关系;
  3. 你手上的旧文件只是一堆加密页,缺了密钥就是随机数据。

这就是为什么「微信记录只在当前设备有效」——不是因为微信故意删,而是加密设计本身把数据锁在了设备上。想跨设备看,只能走官方迁移(迁移时微信会把数据重新加密成目标设备能解的形式)。

实践中最容易踩的坑

  • 以为改了扩展名就能打开:.db 只是文件名,和内部格式无关。
  • 以为有万能密钥:网上流传的「7 位密钥」只对特定年代、特定平台的库有效。
  • 忘了 WAL 文件:SQLite 有 -wal 和 -shm 两个伴生文件,只复制 .db 会丢掉最近未合并的写入。
  • 在库运行中读取:一定先完全退出微信,否则可能读到不一致的页。

正规的替代方案

如果目标只是「看到聊天内容」,完全不需要碰数据库:

  • 手机端迁移到电脑,电脑端完整浏览与搜索;
  • 重要对话合并转发给自己,落成可复制的文本;
  • 需要长期存档,用导出工具走「迁移后的电脑端目录」这条路,比在手机上折腾 root 稳得多。

把加密库当研究对象是一回事,把自己的数据救出来是另一回事——后者有更省事的路。

相关阅读