ZemerTeam/zemer-cipher

GitHub: ZemerTeam/zemer-cipher

一个独立的 Kotlin Android 库,用于 YouTube signature cipher 反混淆、n-parameter 转换与 PoToken 生成,并通过远程配置实现 player 轮换后的应用自愈。

Stars: 1 | Forks: 1

# zemer-cipher 用于 YouTube cipher 反混淆和 PoToken 生成的 Android 库。 ## 来源与采用 此处的 WebView signature-cipher / n-transform 解密代码(`CipherDeobfuscator`、`CipherWebView`, 以及注入的 `window._cipherSigFunc`)最初由我 ([alltechdev](https://github.com/alltechdev))编写 —— 首次于 **2026-02-12** 在 Zemer 应用中实现 ([`f905d49`](https://github.com/ZemerTeam/zemer-app/commit/f905d49da8b4486b659fa32d68e2f45f939fb56a)), 随后于两天后的 **2026-02-14** 添加到了 [Metrolist](https://github.com/MetrolistGroup/Metrolist) ([`0750a63d`](https://github.com/MetrolistGroup/Metrolist/commit/0750a63d74d69082b81ae8868b06edab51fb3875))。 此仓库即为同一套代码,并已提取为独立的 Android 库 (`com.zemer:cipher`)。 **远程配置:** Zemer 应用和 Metrolist 在运行时(通过 `PlayerConfigStore`)从该仓库的 `master` 分支获取 `player_configs.json`,以实现在无需应用更新的情况下自愈 YouTube player 轮换。 **代码复用:** 该解密代码也被复制到了许多其他项目中 —— 这些项目仅打包了 代码,且不会从这里拉取配置更新。已验证的示例包括: - [Echo-Music](https://github.com/EchoMusicApp/Echo-Music) - [Flow](https://github.com/A-EDev/Flow) - [vivi-music](https://github.com/vivizzz007/vivi-music) - [Kreate](https://github.com/knighthat/Kreate) - [Meld](https://github.com/FrancescoGrazioso/Meld) ……以及数十个其他分支和衍生应用。 ## 功能 - 用于 YouTube 流媒体 URL 的 Signature cipher 反混淆 - 用于避免限流的 N-parameter 转换 - 使用 BotGuard 生成 PoToken - **远程可更新的 player 配置** —— 推送到此仓库 `master` 分支的配置可在几分钟内修复已部署的应用,无需发布 APK ## Player 配置 (`library/src/main/assets/player_configs.json`) YouTube 会频繁轮换其 `player_ias` JS;每次轮换都需要一个针对特定 player 的配置 (sig 调用表达式、n-transform URL 类、signatureTimestamp)。所有配置都存在于 **同一个 JSON 文件**中,该文件是: 1. 作为离线默认配置**打包**在 APK 中, 2. 在运行时由 `PlayerConfigStore` 从该仓库的原始 `master` URL 获取 (6 小时的 TTL + ETag),并且**在未知的 player 导致解密失败时立即强制刷新** —— 因此向 `master` 推送新条目即是部署过程, 3. 由 `zemer-app` 测试工具读取 —— 应用、设备和测试之间不会产生脱节。 ### 条目结构 (schemaVersion 1) ``` "445213fb": { "sig": "mP(4,155,INPUT)", "nClass": "Yx", "sts": 20613, "aliases": ["d62bd338"] } ``` - key —— 来自 player JS URL 的 8 位十六进制 player hash;`aliases` —— 前 10000 字节 md5 的后备哈希 - `sig` —— signature 反混淆调用,锁定为 `name(int,int,INPUT)` - `nClass` —— 用于 n-transform IIFE 的 URL 类(由本地模板构建) - `sts` —— player 的 signatureTimestamp ### 添加轮换后的 player 1. 在 `zemer-app` 中:运行 `node tests/validate-player-config.mjs ` —— 解密真实的流 并检查 CDN 是否返回 **HTTP 206**(这是唯一的真实基准;多组常量对可能都能“解密”,但只有一组会被接受)。它会打印出可直接粘贴的 JSON 条目。 2. 将该条目添加到这里的 `player_configs.json` 中。重复的 hash/alias 会导致整个 文件被拒绝 —— 请运行单元测试。 3. 推送到 `master` —— 已部署的应用会在几分钟内从该 URL 自愈。 4. 之后需在 `zemer-app` 中更新 submodule 指针(以保持打包的默认配置保持最新)。 ### 安全模型 `PlayerConfigParser` 是验证边界:每个值都通过 regex 锁定,因此远程数据 永远无法向 cipher WebView 中注入自由格式的 JS。无效条目会被跳过;无效 文件(包括 hash/alias 冲突)会被整体拒绝,并且设备会保留其 最后一次有效表。**仅在**发生破坏性的结构更改时才升级 `schemaVersion` —— 较旧的应用会拒绝 较新的 schema 文件,并继续使用其最后一次的有效表运行。 使用 `./gradlew :library:testDebugUnitTest` 运行测试。`config-parity/` 固定数据(fixtures)与 `zemer-app` 工具 共享:文件级别的接受/拒绝判定(以及 n-IIFE 模板)在两个读取器之间保持逐字节一致。 ## 用法 ### 初始化 ``` // Initialize in your Application class ZemerCipher.initialize( context = applicationContext, proxy = yourProxy, // optional debugLogging = BuildConfig.DEBUG // optional ) ``` ### Cipher 反混淆 ``` // Deobfuscate a signature cipher URL val deobfuscatedUrl = CipherDeobfuscator.deobfuscateStreamUrl(signatureCipher, videoId) // Transform n-parameter in URL val transformedUrl = CipherDeobfuscator.transformNParamInUrl(url) ``` ### PoToken 生成 ``` val generator = PoTokenGenerator() val result = generator.getWebClientPoToken(videoId, sessionId) // result.playerRequestPoToken - for player requests // result.streamingDataPoToken - for streaming data requests ``` ## 致谢 - PoToken 生成模式基于 [BgUtils](https://github.com/LuanRT/BgUtils) (MIT License) - Cipher 函数提取使用了标准的 YouTube 反混淆技术(如 yt-dlp、NewPipe 等所记录的) 所有其他代码(WebView 实现、运行时执行、n-parameter 转换逻辑)均为自定义实现。 ## 许可证 GPL-3.0
标签:Android开发, BotGuard, Homebrew安装, Kotlin, YouTube, 云资产清单, 代码混淆, 后台面板检测, 逆向工程, 音视频解析