第三方 EXE 如何启动 MJYBrowser
第三方启动器持有授权码时,不能把授权码直接传给 chrome.exe。正确方式是在启动前生成一次性加密 launch token,再通过 --launch-token 传给浏览器。浏览器启动后直连授权服务完成 nonce 挑战和 Ed25519 验签。
整体链路
启动授权分为“启动器生成 token”和“浏览器在线验签”两段。你的 EXE 只负责生成一次性 token 并启动浏览器;授权是否通过由 chrome.exe 和授权服务共同完成。
你的 EXE
-> 读取授权码 auth_code
-> 生成 JSON 明文载荷 code + ts + jti + purpose
-> AES-256-GCM 加密
-> base64 得到 launch_token
-> 启动 chrome.exe --launch-token="<launch_token>"
-> chrome.exe 直连授权服务 POST /api/v1/license/sign
-> 授权服务解密 token、校验授权码、消费 jti、返回 Ed25519 签名结果
-> chrome.exe 验签通过后继续启动,失败则进程退出
MJYLicenseLease.json。如果本地 signed lease 有效,本次启动可不联网;如果没有有效 lease,才会使用 --launch-token 发起在线挑战。生成 launch token
每次启动都要重新生成 token。token 内部明文是一个 JSON,随后使用 AES-256-GCM 加密,最终输出 base64 字符串。
code浏览器授权码。只进入加密载荷,不直接出现在 chrome.exe 参数里。
ts当前 Unix 秒。服务端默认按 30 秒新鲜度窗口校验。
jti16 字节随机数转 32 位 hex。服务端会消费,重复使用会拒绝。
purpose固定写 chrome-launch,用于区分 token 用途。
{
"code": "你的授权码",
"ts": 1710000000,
"jti": "32位hex随机字符串",
"purpose": "chrome-launch"
}
算法 AES-256-GCM
key 32 字节密钥,和服务端 license.token_encryption_key 一致
nonce 12 字节随机数,每次重新生成
明文 上面的 JSON
输出 base64(nonce || ciphertext || tag)
license.token_encryption_key 写进 EXE。更安全的方式是由你的服务端生成 launch token,客户端 EXE 只拿 token 启动浏览器。启动器伪代码
下面是你自己的 EXE 需要实现的最小逻辑。语言不限,C#、C++、Go、Rust 都可以,只要加密输出格式一致。
auth_code = 用户输入 / 配置读取 / 平台下发
payload = JSON.stringify({
code: auth_code,
ts: 当前Unix秒,
jti: 16字节随机数转32位hex,
purpose: "chrome-launch"
})
nonce = 随机12字节
ciphertext_and_tag = AES_256_GCM_Encrypt(key, nonce, payload)
launch_token = Base64(nonce + ciphertext_and_tag)
启动 chrome.exe:
--launch-token="<launch_token>"
--auth-url="https://api.jimuie.com/api/v1/license/sign"
--mjy-mode=global-fp
--fp-config="D:\profiles\env-a\fp-config.json"
--user-data-dir="D:\profiles\env-a\profile"
启动命令
最小启动只需要 --launch-token 和独立用户数据目录。生产环境可以按业务需要追加模式、指纹配置、代理和缓存目录。
"D:\MJYBrowser\chrome.exe" ^
--launch-token="<一次性加密token>" ^
--user-data-dir="D:\profiles\env-a\profile" ^
--no-first-run ^
about:blank
"D:\MJYBrowser\chrome.exe" ^
--launch-token="<一次性加密token>" ^
--auth-url="https://api.jimuie.com/api/v1/license/sign" ^
--mjy-mode=global-fp ^
--fp-config="D:\profiles\env-a\fp-config.json" ^
--user-data-dir="D:\profiles\env-a\profile" ^
--disk-cache-dir="D:\profiles\env-a\cache" ^
--proxy-server="socks5://127.0.0.1:1080" ^
--no-first-run ^
about:blank
"D:\MJYBrowser\chrome.exe" ^
--launch-token="<一次性加密token>" ^
--mjy-mode=global-fp ^
--fp-config="D:\profiles\env-a\fp-config.json" ^
--user-data-dir="D:\profiles\env-a\profile" ^
--remote-debugging-port=41729 ^
--remote-allow-origins=* ^
--no-first-run ^
about:blank
用现成生成器验证
平台仓库内置 tokengen,它的逻辑就是第三方启动器需要实现的逻辑。你可以先用它验证授权码、加密密钥和启动命令是否正确。
cd /mnt/disk2/chromium/jimu-platform
go run ./cmd/tokengen \
--key "<license.token_encryption_key的base64值>" \
--auth-code "<授权码>"
go run ./cmd/tokengen \
--key "<license.token_encryption_key的base64值>" \
--auth-code "<授权码>" \
--chrome "D:\MJYBrowser\chrome.exe" \
--user-data-dir "D:\profiles\env-a\profile" \
--print-cmd
GOOS=windows GOARCH=amd64 go build -o tokengen.exe ./cmd/tokengen/
生产安全边界
- 内部可信启动器可以把 AES-GCM 生成逻辑直接编进 EXE,但要接受密钥可能被逆向的风险。
- 外部分发启动器建议调用你的服务端接口换取一次性 launch token,不要在客户端内置
license.token_encryption_key。 - MCP token 不是 launch token。MCP token 只用于平台编排和启动后自动化控制;浏览器启动授权仍然依赖
--launch-token。如果 Cursor 只有浏览器授权码,应先调用browser.launch_token生成 launch token。 - 授权码也不是 launch token。授权码只能进入加密载荷,不能直接作为
--launch-token传给chrome.exe。
Control API(待补充)
后续用于整理 HTTP 管理面和 WSS 主控制面,包括环境、标签、导航、evaluate、截图、事件订阅和下载处理。
fp-config 画像(待补充)
后续用于整理指纹画像字段、版本族一致性、代理、存储目录、Canvas/WebGL/Audio 噪声和 BrowserScan 验收约束。
托管标签(待补充)
后续用于整理 managed-tabs 模式下 envId、tabId、独立缓存、移动端视口和单标签单环境的接入方式。
后续文档位置
这个页面已按文档中心结构预留目录。后续可以继续补充 Control API、fp-config、managed-tabs、代理认证和验收流程,不需要重做页面结构。