// Jose $decrypt: verifyParam(base64) -> 明文 JSON。 // 复用 jose_encrypt.js 的单 realm 沙箱; realm.global 暴露 $encrypt/$encode/$decrypt。 // CLI: node tools/jose_decrypt.js '' -> stdout: 明文 JSON const fs = require("fs"), vm = require("vm"), path = require("path"); const ENC_PATH = path.join(__dirname, "..", "out", "captcha_net", "js_07_rm_static_captcha_js_encrypt_ee7d2a41_js.js"); const KEY = "c7b645db-65e8-401f-b38c-4c07c5fff247"; function makeBox() { const sandbox = { console: { log: () => {}, error: () => {}, warn: () => {} }, setTimeout, clearTimeout, setImmediate, queueMicrotask, Buffer, btoa: (s) => Buffer.from(s, "binary").toString("base64"), atob: (s) => Buffer.from(s, "base64").toString("binary"), }; vm.createContext(sandbox); sandbox.window = sandbox; sandbox.self = sandbox; sandbox.global = sandbox; vm.runInContext(fs.readFileSync(ENC_PATH, "utf-8"), sandbox, { filename: "encrypt.js", timeout: 30000 }); const factory = sandbox.webpackJsonp[0][1]["088e"]; const rq = (id) => id === "b639" ? { Buffer } : id === "dd40" ? (x) => x : {}; const mod = { exports: {} }; factory(mod, mod.exports, rq); if (!sandbox.Jose) throw new Error("Jose 未加载"); return sandbox; } function decrypt(sandbox, verifyParamB64) { // base64 -> bytes (单 realm: 用沙箱 atob + charCodeAt) sandbox.__done = null; sandbox.__out = null; vm.runInContext(` globalThis.__dec = function(vp){ var s = globalThis.atob(vp); var u8 = new Uint8Array(Array.prototype.map.call(s, function(c){return c.charCodeAt(0);})); globalThis.__out=null; globalThis.__done=null; Jose.call("$decrypt", [u8, ${JSON.stringify(KEY)}, { suc: function(v){ var o=""; for(var i=0;i { const t0 = Date.now(); const iv = setInterval(() => { if (sandbox.__done !== null || Date.now() - t0 > 5000) { clearInterval(iv); resolve(sandbox.__done === "ok" ? sandbox.__out : (sandbox.__out || "ERR:timeout")); } }, 5); }); } module.exports = { makeBox, decrypt, KEY }; if (require.main === module) { const arg = process.argv[2]; if (!arg) { console.error("usage: node jose_decrypt.js ''"); process.exit(2); } const box = makeBox(); decrypt(box, arg).then((out) => { if (out && out.indexOf("ERR:") === 0) { console.error(out); process.exit(1); } process.stdout.write(out || ""); }); }