mirror of
https://github.com/Evil0ctal/WeChat-Channels-Video-File-Decryption.git
synced 2026-10-25 17:36:33 +08:00
问题修复: - 修复解密超过 80MB 视频时页面崩溃的问题(issue #4 #6 #8) - 根因:旧实现将整段视频经 CDP 管道传入浏览器做 XOR,base64 膨胀后超过 Chromium DevTools 协议 100MB 单条消息上限,导致页面被关闭 - 将 XOR 解密从浏览器移至 Node.js 端,浏览器仅负责生成 128KB 密钥流, 视频数据不再进入浏览器,文件大小不再受此限制 新功能: - 新增 lib/decrypt.js 解密核心模块(decryptBuffer / assertMp4) - 新增 decode_key 密钥流 LRU 缓存,命中后跳过浏览器 WASM 调用, 可通过 KEYSTREAM_CACHE_MAX 环境变量配置上限(默认100) - 新增 test/decrypt.test.js 单元测试,覆盖 120MB 大文件边界场景 其他: - Dockerfile 补充拷贝 lib 目录,修复容器内模块缺失 - worker.html 的 decryptVideo 标注为已弃用(保留向后兼容) - 更新 README 架构说明,补充大文件故障排除与「如何获取 decode_key」说明 - 版本号升级至 2.1.0
43 lines
1.6 KiB
JavaScript
43 lines
1.6 KiB
JavaScript
/**
|
|
* 视频解密核心(纯函数,Node.js 端执行)
|
|
*
|
|
* 微信视频号仅加密文件前 KEYSTREAM_SIZE(128KB) 字节,其余为明文。
|
|
* 解密无需浏览器:浏览器只负责用 WASM 生成 128KB 密钥流,XOR 在此完成。
|
|
* 旧实现把整段视频经 CDP 管道传入浏览器,会触发 DevTools 协议 100MB 单条
|
|
* 消息上限,导致大文件解密时页面崩溃(见 issue #4 / #6 / #8)。
|
|
*
|
|
* @module lib/decrypt
|
|
*/
|
|
|
|
// 微信加密作用的字节数(密钥流长度)
|
|
const KEYSTREAM_SIZE = 131072;
|
|
|
|
/**
|
|
* 对加密视频执行 XOR 解密
|
|
* @param {Buffer} encrypted 原始加密视频 Buffer
|
|
* @param {Buffer} keystream 128KB 密钥流 Buffer
|
|
* @returns {Buffer} 解密后的视频 Buffer(明文部分原样保留)
|
|
*/
|
|
function decryptBuffer(encrypted, keystream) {
|
|
const decrypted = Buffer.from(encrypted); // 拷贝一份,明文部分原样保留
|
|
const decryptLen = Math.min(KEYSTREAM_SIZE, encrypted.length, keystream.length);
|
|
for (let i = 0; i < decryptLen; i++) {
|
|
decrypted[i] = encrypted[i] ^ keystream[i];
|
|
}
|
|
return decrypted;
|
|
}
|
|
|
|
/**
|
|
* 校验解密结果是否为合法 MP4(偏移 4 处应为 ftyp 签名)
|
|
* @param {Buffer} buffer 解密后的视频 Buffer
|
|
* @throws {Error} 当签名缺失时(通常是 decode_key 不匹配)
|
|
*/
|
|
function assertMp4(buffer) {
|
|
const ftyp = buffer.toString('utf8', 4, 8);
|
|
if (ftyp !== 'ftyp') {
|
|
throw new Error('解密失败:未找到 MP4 ftyp 签名,请检查 decode_key');
|
|
}
|
|
}
|
|
|
|
module.exports = { KEYSTREAM_SIZE, decryptBuffer, assertMp4 };
|