终于找到微信聊天记录SQLite数据库文件解密方法了,一起来看看吧!

本文主要是介绍终于找到微信聊天记录SQLite数据库文件解密方法了,一起来看看吧!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://github.com/xuchengsheng/

图片

  • 获取当前登录微信的微信昵称、账号、手机号、邮箱、秘钥、微信Id、文件夹路径

  • 将微信PC的多个聊天记录数据库合并为单一数据库文件

  • 支持微信聊天对话窗口(文本消息,引用消息,图片消息,表情消息,卡片链接消息,系统消息,等)

  • 综合管理微信会话、联系人、群聊与朋友圈

  • 支持导出微信各类记录(聊天记录,联系人,群聊,等)

  • 查看历史朋友圈记录,超越三日限制,随时回看朋友圈历史

  • 展示好友数、群聊数及今日收发消息总量的微信统计功能

  • 过去15天内每日微信消息数量统计

  • 最近一个月内微信互动最频繁的前10位联系人

  • 展示微信消息类别占比图表

  • 展示微信最近使用的关键字词云图

图片

图片

图片

图片

图片

图片

图片

图片

图片

🚀快速启动

安装包方式部署

  • 点击下载 wx-dump-4j-bin.tar.gz

  • 解压缩 wx-dump-4j-bin.tar.gz,进入 bin 目录

  • 双击start.bat启动文件

  • 启动成功后访问:http://localhost:8080

源码方式部署

  • 下载源码git clone https://github.com/xuchengsheng/wx-dump-4j.git

  • 安装后端依赖cd wx-dump-4j & mvn clean install

  • 使用开发工具启动 com.xcs.wx.WxDumpApplication

  • 安装前端依赖cd wx-dump-ui & npm install

  • 启动前端服务npm run start

  • 访问:http://localhost:8000

📚实现原理

  • 微信SQLite数据库文件解密实现,基于HmacSHA1的安全解密算法

⛔️使用限制

本软件仅适用于Windows操作系统。我们目前不支持macOS、Linux或其他操作系统。如果你在尝试在非Windows系统上运行本软件时可能遇到兼容性问题,这些问题可能导致软件无法正常运行或产生其他意外后果。

操作系统支持情况
Windows支持
macOS不支持
Linux不支持

微信SQLite数据库文件解密实现

  • 微信SQLite数据库文件解密实现

    • SQLite页结构描述

    • SQLite页结构图

    • 解密实现过程

    • 源码地址

SQLite页结构描述

微信SQLite数据库文件以每个页面4096字节的大小进行划分,这些页面组成了文件的基本结构。每个页面内部包含了关键的元素,包括盐值、加密后的内容、初始化向量(IV)、哈希值(hashMac),以及用于保留的空字节。这个结构在整个数据库文件中起到了关键的组织和安全保障的作用。

首个页面是独特的,它包含了生成加密密钥所需的盐值、加密后的内容、初始化向量(IV)、哈希值(hashMac),以及用于保留的空字节。盐值在加密密钥生成过程中发挥着关键的作用,而哈希值则用于验证密钥的正确性,提供了额外的安全层。空字节的存在为未来可能的拓展或变化预留了空间。

随后的页面结构与首个页面相似,仍然包括了加密后的内容、初始化向量(IV)以及用于保留的空字节。这种一致性的结构确保了整个数据库文件的统一性和安全性,使得每个页面都能够独立存储经过加密的数据块,并在需要时通过初始化向量进行解密。这种巧妙的设计使得SQLite数据库文件在存储和保护数据方面表现出色。

SQLite页结构图

图片

解密实现过程

DecryptServiceImpl类是一个解密服务的实现,专门用于解密SQLite数据库文件。首先,它定义了SQLite数据库文件的文件头、加密算法(HmacSHA1)、页面大小(4096字节)、迭代次数(64000次)以及密钥长度(32字节)。主要功能由wechatDecrypt方法实现,该方法接收密码和解密业务对象作为参数。

wechatDecrypt方法内部,首先通过FileInputStream读取数据库文件内容,提取文件头、盐值、第一页信息,包括内容、IV、hashMac和保留字段。随后,利用PBKDF2算法和用户提供的密码生成密钥,并根据提取的盐值和hashMac验证密钥的正确性。

如果密钥验证成功,便创建输出文件,写入SQLite文件头,并对第一页进行解密,写入解密后的内容和保留字段。接着,循环处理后续数据块,逐一解密并写入到输出文件。整个过程保证了对SQLite数据库文件的完整性和保密性的维护。

在解密过程中,doDecrypt方法使用AES/CBC/NoPadding模式对数据进行解密。为了处理大文件,splitDataPages方法将文件内容分割成多个页面进行逐一处理。

最后,通过checkKey方法检查密钥的有效性,确保解密过程中密钥的正确性。该类结合了多重密码学技术,保障了对SQLite数据库文件的高效且安全的解密操作。

public class DecryptServiceImpl implements DecryptService {
    /**     * SQLite数据库的文件头     */    private static final String SQLITE_FILE_HEADER = "SQLite format 3\u0000";
    /**     * 算法     */    private static final String ALGORITHM = "HmacSHA1";
    /**     * 一页的大小     */    private static final int DEFAULT_PAGESIZE = 4096;
    /**     * 迭代次数     */    private static final int ITERATIONS = 64000;
    /**     * Key长度     */    private static final int HASH_KEY_LENGTH = 32;
    @Override    public void wechatDecrypt(String password, DecryptBO decryptBO) {        // 创建File文件        File file = new File(decryptBO.getInput());
        try (FileInputStream fis = new FileInputStream(file)) {            // 文件大小            byte[] fileContent = new byte[(int) file.length()];            // 读取内容            fis.read(fileContent);
            // 提取盐值            byte[] salt = Arrays.copyOfRange(fileContent, 0, 16);            // 提取第一页            byte[] firstPage = Arrays.copyOfRange(fileContent, 16, DEFAULT_PAGESIZE);            // 提取第一页的内容与IV            byte[] firstPageBodyAndIv = Arrays.copyOfRange(firstPage, 0, firstPage.length - 32);            // 提取第一页的内容            byte[] firstPageBody = Arrays.copyOfRange(firstPage, 0, firstPage.length - 48);            // 提取第一页IV            byte[] firstPageIv = Arrays.copyOfRange(firstPage, firstPage.length - 48, firstPage.length - 32);            // 提取第一页的hashMac            byte[] firstPageHashMac = Arrays.copyOfRange(firstPage, firstPage.length - 32, firstPage.length - 12);            // 提取第一页的保留字段            byte[] firstPageReservedSegment = Arrays.copyOfRange(firstPage, firstPage.length - 48, firstPage.length);
            // 生成key            byte[] key = Pbkdf2HmacUtil.pbkdf2Hmac(ALGORITHM, HexUtil.decodeHex(password), salt, ITERATIONS, HASH_KEY_LENGTH);
            byte[] macSalt = new byte[salt.length];            for (int i = 0; i < salt.length; i++) {                macSalt[i] = (byte) (salt[i] ^ 58);            }            // 秘钥匹配成功            if (checkKey(key, macSalt, firstPageHashMac, firstPageBodyAndIv)) {                File outputFile = new File(decryptBO.getOutput());                File parentDir = outputFile.getParentFile();
                // 检查父目录是否存在,如果不存在,则创建                if (!parentDir.exists()) {                    parentDir.mkdirs();                }
                // 解密并写入新文件                try (FileOutputStream deFile = new FileOutputStream(outputFile)) {                    deFile.write(SQLITE_FILE_HEADER.getBytes());                    deFile.write(doDecrypt(key, firstPageIv, firstPageBody));                    deFile.write(firstPageReservedSegment);                    // 解密后续数据块                    for (byte[] page : splitDataPages(fileContent)) {                        byte[] iv = Arrays.copyOfRange(page, page.length - 48, page.length - 32);                        byte[] body = Arrays.copyOfRange(page, 0, page.length - 48);                        byte[] reservedSegment = Arrays.copyOfRange(page, page.length - 48, page.length);                        deFile.write(doDecrypt(key, iv, body));                        deFile.write(reservedSegment);                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }    }
    /**     * 使用AES/CBC/NoPadding模式进行解密     *     * @param key   密钥     * @param iv    初始化向量     * @param input 待解密的数据     * @return 解密后的数据     * @throws GeneralSecurityException 抛出异常     */    private byte[] doDecrypt(byte[] key, byte[] iv, byte[] input) throws GeneralSecurityException {        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);        return cipher.doFinal(input);    }
    /**     * 将数据分割成多个页面     *     * @param fileContent 文件内容的字节数组     * @return 分割后的页面列表     */    private List<byte[]> splitDataPages(byte[] fileContent) {        List<byte[]> pages = new ArrayList<>();        for (int i = DEFAULT_PAGESIZE; i < fileContent.length; i += DEFAULT_PAGESIZE) {            // 计算每个分割页面的结束位置            int end = Math.min(i + DEFAULT_PAGESIZE, fileContent.length);            byte[] slice = new byte[end - i];            // 将数据复制到新的页面中            System.arraycopy(fileContent, i, slice, 0, slice.length);            pages.add(slice);        }        return pages;    }
    /**     * 检查密钥是否有效     *     * @param byteKey 密钥的字节数组     * @param macSalt MAC盐值     * @param hashMac 预期的MAC哈希值     * @param message 消息内容     * @return 如果密钥有效返回true,否则返回false     * @throws Exception 抛出异常     */    private boolean checkKey(byte[] byteKey, byte[] macSalt, byte[] hashMac, byte[] message) throws Exception {        // 使用PBKDF2算法生成MAC密钥        byte[] macKey = Pbkdf2HmacUtil.pbkdf2Hmac(ALGORITHM, byteKey, macSalt, 2, 32);        Mac mac = Mac.getInstance(ALGORITHM);        SecretKeySpec keySpec = new SecretKeySpec(macKey, ALGORITHM);        mac.init(keySpec);        // 更新MAC计算的消息内容        mac.update(message);        // 添加额外的数据到消息中        mac.update(new byte[]{1, 0, 0, 0});        // 比较计算出的MAC值和预期的MAC值是否相同        return Arrays.equals(hashMac, mac.doFinal());    }}

  • https://github.com/xuchengsheng/wx-dump-4j

  • com.xcs.wx.service.impl.DecryptServiceImpl

这篇关于终于找到微信聊天记录SQLite数据库文件解密方法了,一起来看看吧!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/970027

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时