零存储 完全免费 开源内核
返回首页

概述

JSShield 是一款专业的 JavaScript 代码混淆与保护服务,提供多种混淆策略和虚拟机保护(JSVMP)能力。

ℹ️ 提示

本文档面向集成开发者,介绍如何通过 API 调用 JSShield 的混淆服务。如果你只是想在线使用,请访问 Web 控制台

核心能力

  • 字符串数组加密 — 将代码中的字符串提取到加密数组中,通过动态解码访问
  • 控制流平坦化 — 将线性代码转换为状态机,增加逆向难度
  • 死代码注入 — 插入无意义的代码分支,干扰静态分析
  • JSVMP 虚拟机保护 — 将核心函数编译为自定义字节码,在 VM 中运行
  • 反调试保护 — 检测开发者工具并触发保护机制

接口地址

ℹ️ 基础 URL

所有 API 接口的基础地址:https://jsshield.lltxj.top

示例:混淆接口完整地址为 https://jsshield.lltxj.top/api/v1/obfuscate

https://jsshield.lltxj.top/api/v1/obfuscate

使用限制

⚠️ 重要限制
  • 并发限制:每个 IP 同时只能有 1 个请求在处理中
  • 频率限制:每个 IP 每分钟最多 60 次请求
  • 大小限制:单次请求最大 10MB
  • 认证要求:必须携带有效的 X-API-Token 请求头

获取令牌

调用 API 需要令牌(Token)进行身份验证。获取方式如下:

  1. 访问 Web 控制台首页
  2. 点击顶部导航栏的「生成令牌」按钮,或滚动到页面底部的 Token 区域
  3. 确认使用须知后系统自动完成验证并生成令牌
  4. 复制令牌保存到环境变量或配置文件中
ℹ️ 提示
  • 令牌有效期为 30 天,过期后需重新生成
  • 令牌是无状态的,可多设备共用
  • 也可以点击页面右上角的「生成令牌」按钮快速跳转到首页 Token 区域
⚠️ 注意

请勿将令牌提交到公开仓库。建议通过环境变量(如 JSSHIELD_TOKEN)传入构建流程。

快速调用示例

使用获取到的令牌调用混淆接口。以下是一个完整的请求示例:

JavaScript · fetch 示例
// JSShield API 快速调用示例 const response = await fetch('https://jsshield.lltxj.top/api/v1/obfuscate', { method: 'POST', headers: { 'Content-Type': 'application/json', // 请求体格式为 JSON 'X-API-Token': 'your-token-here' // 替换为你的实际令牌 }, body: JSON.stringify({ sourceCode: 'function hello() { return "world"; }', // 待混淆的源代码 preset: 'medium' // 使用 medium 预设 }) }); const result = await response.json(); console.log(result.code); // 输出混淆后的代码

认证方式

所有 API 请求需要在请求头中携带令牌。这是唯一的认证方式,不支持 Basic Auth 或 OAuth。

HTTP 请求头
// 在每次请求的 Header 中添加 X-API-Token 字段 X-API-Token: jsshield_v1_xxxxxxxx

令牌缺失或无效时返回 401 Unauthorized

{
  "success": false,
  "error": "Unauthorized",
  "message": "Invalid or missing API token"
}

混淆接口

POST /api/v1/obfuscate

ℹ️ 完整地址

https://jsshield.lltxj.top/api/v1/obfuscate

核心混淆接口,将 JavaScript 源代码混淆为受保护的代码。

请求参数

字段类型必填说明
sourceCodestring待混淆的 JavaScript 源代码(纯文本)
presetstring预设模式名称,如 highultimate
optionsobject自定义混淆选项,会覆盖 preset 中的同名配置
targetstring目标环境:默认 browser,可选 nodeservice-worker

请求示例

{// 使用预设模式快速混淆
  "sourceCode": "function hello(name) { return 'Hello ' + name; }",// 待混淆源码
  "preset": "high"// 预设名称:low / default / medium / high / jsvmp / ultimate 等
}
{// 通过 options 精细控制每个混淆选项
  "sourceCode": "function hello(name) { return 'Hello ' + name; }",
  "options": {
    "compact": true,// 压缩输出代码
    "stringArrayEncoding": ["rc4"],// RC4 加密字符串数组
    "selfDefending": true,// 启用自我保护
    "debugProtection": true// 启用反调试保护
  }
}
# cURL 命令行调用示例
curl -X POST https://jsshield.lltxj.top/api/v1/obfuscate \
  -H "Content-Type: application/json" \
  -H "X-API-Token: YOUR_TOKEN_HERE" \
  -d '{"sourceCode":"function hi(){return 1;}","preset":"high"}'

preset 与 options 的优先级

同时传入时,options 会覆盖 preset 中的同名配置。例如以 high 为基础额外开启调试保护:

{ "preset": "high", "options": { "debugProtection": true } }

响应示例(成功)

{
  "success": true,
  "code": "var _0x1a2b=[...];function hello(_0x3c4d){return _0x1a2b[0]+_0x3c4d;}",// 混淆后的代码
  "engineFingerprint": "a1b2c3d4e5f67890",// 引擎指纹,用于缓存 key 计算
  "stats": {
    "originalSize": 52,// 原始字节大小
    "obfuscatedSize": 89,// 混淆后字节大小
    "ratio": "1.71",// 膨胀比例
    "elapsedMs": 15// 处理耗时(毫秒)
  }
}

响应示例(失败)

{
  "success": false,
  "error": "Invalid token",
  "message": "API令牌无效或已过期,请前往首页重新生成"
}

响应头

响应头说明
X-JSShield-Version服务端版本号(如 4.1.0),用于兼容性判断
X-JSShield-Fingerprint引擎指纹(SHA256 前 16 位),引擎代码变化时自动更新
ℹ️ 引擎指纹说明

指纹仅取决于混淆引擎的实际代码逻辑,与版本号、构建时间无关。当 JSShield 服务端更新混淆引擎代码时,内容哈希会自动变化;仅更新版本号但代码未变时,指纹不变。此值可用于 CI/CD 缓存策略的缓存 key 计算。

版本接口

GET /api/v1/version

ℹ️ 完整地址

https://jsshield.lltxj.top/api/v1/version

获取当前混淆引擎的版本和指纹信息。公开接口,无需携带令牌,适用于 CI/CD 构建开始时快速获取引擎指纹以计算缓存 key、检测服务端引擎是否更新。

响应示例
{ "success": true, "version": "4.1.0",// 服务端语义化版本号 "engineFingerprint": "a1b2c3d4e5f67890",// 引擎代码 SHA256 前 16 位 "timestamp": "2026-05-07T10:30:00.000Z"// 响应时间戳 }
⚠️ 设计说明

此接口为公开端点,仅返回只读的公开信息(版本号 + 引擎指纹哈希),不涉及代码混淆操作。作为缓存失效检测入口,在 CI/CD 流程中需要无门槛调用,避免循环依赖。

健康检查

GET /api/v1/health

ℹ️ 完整地址

https://jsshield.lltxj.top/api/v1/health

用于检测服务连通性,不限制 HTTP 方法。适合在部署脚本或监控系统中使用。

{
  "status": "ok",// 服务状态
  "service": "JSShield Obfuscation API",// 服务标识
  "version": "6.1.5",// 当前版本
  "timestamp": "2025-01-01T00:00:00.000Z",// 服务器时间
  "endpoints": {
    "internal": "/api/obfuscate",// 内部接口路径
    "public": "/api/v1/obfuscate"// 公开接口路径
  }
}

状态码说明

状态码含义说明解决方案
200success请求成功
400BAD_REQUEST请求参数错误检查 sourceCode 是否存在且为字符串
401UNAUTHORIZED令牌无效或缺失前往首页重新生成令牌
403FORBIDDEN挑战过期或验证失败重新发起 challenge 流程
413Request too large超过 10MB 上限减小源文件体积或分包处理
429TOO_MANY_REQUESTS速率限制或并发超限降低请求频率,响应体含 retryAfter 字段
500INTERNAL_ERROR服务器内部错误检查源代码语法是否合法

并发限制详情

每个 IP 同时只能有 1 个请求在处理中。并发超限时返回 429,响应体包含 retryAfter: 5(秒),表示建议等待时间后重试。

限流策略

接口类型频率限制说明
公共 API (/api/v1/*)60 次/分钟/IP面向外部用户的接口
内部 API (/api/*)30 次/分钟/IP面向内部系统的接口

超限时返回 429 Too Many Requests 状态码。建议在客户端实现指数退避重试策略。

预设列表

选择预设模式可以快速应用最佳实践配置。也可通过 options 覆盖特定选项。

low · 低强度

基础混淆 + 自我保护,适合对性能要求高的场景

default · 默认

标准混淆配置,平衡安全性和性能

medium · 中强度

控制流平坦化 + 死代码注入 + 字符串拆分

high · 高强度

全部基础选项开启,适合商业产品保护

jsvmp · 虚拟机保护

将核心函数编译为字节码,在自定义虚拟机中运行

anti-debug · 反调试

多层反调试:DevTools/Console/时间检测 + 反内存转储

anti-reverse · 防逆向

反 LLM 保护 + 诱饵函数 + 控制流平坦化

ultimate · 终极保护

三重防护全开:JSVMP + 反调试 + 防逆向

预设组合

通过 preset + options 实现组合。例如在 high 基础上叠加反调试:

{// 以 high 为基础,额外开启调试保护和定时检测
  "preset": "high",
  "options": {
    "debugProtection": true,// 开启无限 Debuger 检测
    "debugProtectionInterval": 2000// 每 2 秒检测一次
  }
}

各预设的完整选项可通过 GET /api/v1/options 查询。

性能参考

以下数据基于 10KB 典型代码的测试结果(仅供参考,实际因代码复杂度而异):

预设体积膨胀运行时性能损失
low+30~50%<5%
medium+100~200%10~20%
high+300~500%30~50%
jsvmp / ultimate+500~1000%JSVMP 函数慢 5~20 倍

基础选项

选项类型默认值说明
targetstring"browser"目标运行环境
compactbooleantrue压缩输出,移除多余空白
simplifybooleantrue简化代码结构

字符串数组

选项类型默认值说明
stringArraybooleantrue启用字符串数组提取
stringArrayEncodingarray[]编码方式:base64rc4,可组合如 ["base64","rc4"]
stringArrayThresholdnumber0.75字符串提取率 (0~1),越低提取越多
splitStringsbooleanfalse将长字符串拆分为多个片段

控制流保护

选项类型默认值说明
controlFlowFlatteningbooleanfalse控制流平坦化,将 if/else 转为 switch 状态机
deadCodeInjectionbooleanfalse注入死代码块,干扰静态分析
numbersToExpressionsbooleanfalse将数字字面量转为复杂表达式

JSVMP 保护

选项类型默认值说明
jsvmpProtectionbooleanfalse启用 JSVMP 字节码虚拟机保护
jsvmpAutoDetectbooleantrue自动检测需要保护的函数(非下划线开头且长度>2)
jsvmpTargetFunctionsarray[]手动指定需要 VM 保护的函数名列表
jsvmpDynamicOpcodesbooleanfalse每次编译生成不同的操作码映射

反调试选项

选项类型默认值说明
debugProtectionbooleanfalse基础调试保护(无限 Debugger 检测)
selfDefendingbooleanfalse自我保护,检测被篡改时触发自毁
disableConsoleOutputbooleanfalse禁用 console.log/warn/error 输出
advancedDebugProtectionbooleanfalse高级反调试(DevTools/Console/时间检测)
antiMemoryDumpbooleanfalse反内存转储,防止内存快照分析

完整选项表

选项类型默认值说明
targetstring"browser"目标环境
compactbooleantrue压缩输出
simplifybooleantrue简化代码结构
stringArraybooleantrue字符串数组
stringArrayEncodingarray[]编码方式
stringArrayThresholdnumber0.75提取率 (0~1)
splitStringsbooleanfalse拆分长字符串
controlFlowFlatteningbooleanfalse控制流平坦化
deadCodeInjectionbooleanfalse死代码注入
numbersToExpressionsbooleanfalse数字转表达式
selfDefendingbooleanfalse自我保护
debugProtectionbooleanfalse调试保护
advancedDebugProtectionbooleanfalse高级反调试
antiMemoryDumpbooleanfalse反内存转储
disableConsoleOutputbooleanfalse禁用 console
jsvmpProtectionbooleanfalseJSVMP 保护
jsvmpAutoDetectbooleantrue自动检测函数
jsvmpTargetFunctionsarray[]手动指定函数名
jsvmpDynamicOpcodesbooleanfalse动态操作码
antiLlmProtectionbooleanfalse反 AI/LLM 分析
decoyFunctionsbooleanfalse注入诱饵函数

Webpack 集成

⚠️ API 混淆开关与失败处理机制
  • 默认开启:ENABLE_API_OBFUSCATION = true
  • 失败即终止:API 请求失败时构建流程立即终止,绝不输出未混淆代码
  • Webpack / Vite / Rollup:通过 throw e 抛出异常中断构建
  • Node.js 脚本:通过 process.exit(1) 终止进程
  • 跳过混淆:设置 ENABLE_API_OBFUSCATION = false
webpack.jsshield.js
const https = require('https'); const http = require('http'); // ========== 配置区 ========== const ENABLE_API_OBFUSCATION = true; // 总开关:设为 false 跳过所有混淆 const JSSHIELD_API = 'https://jsshield.lltxj.top/api/v1/obfuscate'; const JSSHIELD_PRESET = 'high'; // 预设模式 const JSSHIELD_TOKEN = process.env.JSSHIELD_TOKEN || 'YOUR_TOKEN_HERE'; // 从环境变量读取令牌 // ========== 核心混淆函数 ========== async function obfuscateCode(code) { if (!ENABLE_API_OBFUSCATION) { console.log('[JSShield] SKIP: API obfuscation disabled'); return code; } return new Promise((resolve, reject) => { const url = new URL(JSSHIELD_API); const client = url.protocol === 'https:' ? https : http; const req = client.request({ hostname: url.hostname, port: url.port, path: url.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Token': JSSHIELD_TOKEN } }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { const result = JSON.parse(data); result.success ? resolve(result.code) : reject(new Error(result.message)); }); }); req.on('error', reject); // 网络错误直接 reject req.write(JSON.stringify({ sourceCode: code, preset: JSSHIELD_PRESET })); req.end(); }); } // ========== Webpack 插件导出 ========== module.exports = { plugins: [{ apply(compiler) { compiler.hooks.emit.tapPromise('JSShield', async (compilation) => { for (const filename in compilation.assets) { if (!filename.endsWith('.js')) continue; // 只处理 JS 文件 try { const obfuscated = await obfuscateCode(compilation.assets[filename].source()); compilation.assets[filename] = { source: () => obfuscated, size: () => obfuscated.length }; } catch (e) { throw e; // 失败立即终止构建 } } }) } }] };

Vite 集成

vite.config.js
import { defineConfig } from 'vite'; import fs from 'fs'; import path from 'path'; const API_HOST = 'jsshield.lltxj.top'; const API_TOKEN = process.env.JSSHIELD_TOKEN; // 从环境变量读取 // 核心混淆函数 async function obfuscateCode(code, filePath) { const response = await fetch(`https://${API_HOST}/api/v1/obfuscate`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Token': API_TOKEN }, body: JSON.stringify({ sourceCode: code, preset: 'ultimate', // 使用终极保护预设 target: // 目标环境为浏览器 }) }); const result = await response.json(); if (!result.success) throw new Error(result.message); return result.code; } // Vite 插件:在 closeBundle 钩子中对产物进行混淆 export default defineConfig({ plugins: [{ name: 'jsshield', async closeBundle() { // 构建完成后执行 const appJsPath = path.resolve('dist/assets/app.js'); if (!fs.existsSync(appJsPath)) return; const sourceCode = fs.readFileSync(appJsPath, 'utf-8'); const obfuscatedCode = await obfuscateCode(sourceCode, appJsPath); fs.writeFileSync(appJsPath, obfuscatedCode, 'utf-8'); console.log('✅ JSShield obfuscation completed'); } }] });

Rollup 集成

Rollup 插件结构与 Vite 完全相同(Vite 底层使用 Rollup)。复用上面的 obfuscateCode 函数,仅在钩子上切换:

rollup.config.js
export default { plugins: [{ name: 'jsshield', // generateBundle: 在所有 chunk 生成后、写入磁盘前执行 async generateBundle(options, bundle) { for (const [fileName, chunk] of Object.entries(bundle)) { if (fileName.endsWith('.js') && chunk.type === 'chunk') { const obfuscated = await obfuscateCode(chunk.code, fileName); chunk.code = obfuscated; // 直接替换 chunk 内容 } } } }] };

esbuild 集成

build.mjs
import esbuild from 'esbuild'; import fs from 'fs'; async function build() { await esbuild.build({ entryPoints: ['src/app.js'], bundle: true, outfile: 'dist/app.js', plugins: [{ name: 'jsshield', setup(build) { // onEnd: esbuild 构建完成后触发 build.onEnd(async () => { const code = fs.readFileSync('dist/app.js', 'utf8'); const obfuscated = await obfuscateCode(code, 'dist/app.js'); fs.writeFileSync('dist/app.js', obfuscated); }); } }] }); } build();

Node.js 脚本

scripts/obfuscate.js
const fs = require('fs'); // ========== 配置 ========== const ENABLE_API_OBFUSCATION = true; const API_URL = 'https://jsshield.lltxj.top/api/v1/obfuscate'; const TOKEN = process.env.JSSHIELD_TOKEN || 'YOUR_TOKEN_HERE'; // ========== 混淆函数 ========== async function obfuscate(sourceCode, preset) { if (!ENABLE_API_OBFUSCATION) return sourceCode; const res = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Token': TOKEN }, body: JSON.stringify({ sourceCode, preset }) }); if (!res.ok) throw new Error('API request failed: ' + res.status); const result = await res.json(); if (!result.success) throw new Error(result.message); return result.code; } // ========== 执行构建 ========== async function build() { try { const code = fs.readFileSync('app.js', 'utf8'); const obfuscated = await obfuscate(code, 'high'); fs.writeFileSync('app.js', obfuscated); console.log('[JSShield] ✅ OK'); } catch (e) { console.error('[JSShield] ❌ FAIL:', e.message); process.exit(1); // 失败退出码 1 } } build();

JSVMP 使用指南

JSVMP(JavaScript Virtual Machine Protection)将核心函数编译为自定义字节码,在虚拟机中运行。这是最高级别的保护手段。

自动检测规则

jsvmpAutoDetect: true(默认)时,自动识别符合以下条件的函数:

  • 函数名不以 _ 开头(约定私有函数不受保护)
  • 函数名长度大于 2
  • 包括函数声明、函数表达式、类方法、箭头函数赋值

手动指定保护范围

通过 jsvmpTargetFunctions 精确指定需要保护的函数名:

{// 只保护这两个核心函数
  "jsvmpProtection": true,
  "jsvmpAutoDetect": false,// 关闭自动检测
  "jsvmpTargetFunctions": ["encryptData", "validateToken"]
}
❌ 注意

JSVMP 保护的函数不支持 Source Map。调试时建议先用 defaultmedium 预设测试功能正确性,确认无误后再切换到 JSVMP 预设。

客户端缓存策略

在 CI/CD 构建流程中,相同的源代码 + 相同的混淆选项会产生相同的混淆结果。通过内容寻址缓存(Content-Addressed Cache),可以避免重复调用 API,显著降低构建时间和服务器负载。

核心原理

缓存 key 由 SHA256(源代码 + 混淆选项 + 引擎指纹) 三元组生成。任一因素变化都会导致缓存失效:

缓存 Key 计算函数
const crypto = require('crypto'); // 对 options 的键进行排序,确保相同配置产生相同 hash function computeCacheKey(sourceCode, options, engineFingerprint) { const sorted = Object.keys(options).sort().reduce((acc, k) => { acc[k] = Array.isArray(options[k]) ? [...options[k]].sort() : options[k]; return acc; }, {}); const raw = JSON.stringify({ s: sourceCode, o: sorted, f: engineFingerprint }); return crypto.createHash('sha256').update(raw).digest('hex'); }

工作流程

构建开始
  |
  │  1. GET /api/v1/version → 获取 engineFingerprint
  |
  │  2. hash = SHA256(源代码 + 选项 + engineFingerprint)
  |
  ├─ 3. 检查 .jsshield-cache/{hash}.js 是否存在?
  |     ├─ 存在 → 读取缓存,跳过 API 调用
  |     └─ 不存在 → 调用 POST /api/v1/obfuscate
  |                   ├─ 成功 → 写入缓存 + 输出结果
  |                   └─ 失败 → 终止构建(不输出未&#u6DF7;&#u6DC6;代码)
  |
  └─ 构建ָ成

利弊分析

维度说明应对策略
✅ 节省 API 调用相同输入不重复调用
✅ 加速构建缓存命中从秒级降到毫秒级
✅ 持久化缓存独立于 dist/ 目录.gitignore 加入 .jsshield-cache/
✅ 天然去重内容寻址,相同代码不重复存储
⚠️ 引擎更新服务端算法更新后旧缓存可能过时指纹基于引擎代码哈希,代码变化时自动失效;仅版本号变化不影响
⚠️ 缓存膨胀长期积累占用磁盘空间定期清理超过 30 天的缓存,或限制总大小 500MB
⚠️ 多人协作各团队成员各自维护本地缓存正确做法,不应共享。首次构建即生成本地缓存
⚠️ seed=0 随机性每次混淆结果不同但语义等价语义等价即可命中缓存
⚠️ 指纹获取失败Version API 不可用时无法获取指纹降级使用 'unknown' 作为指纹,下次构建自动修正
ℹ️ 推荐配置

.jsshield-cache/ 加入 .gitignore,缓存目录不应提交到 Git 仓库。它是本地构建优化,每个开发者的首次构建会自动生成缓存。

TypeScript 支持

JSShield API 本身不直接处理 TypeScript。推荐的构建流水线如下:

  1. 使用 tscesbuild 将 TypeScript 编译为 JavaScript
  2. 对编译后的 JavaScript 调用 JSShield API 进行混淆
  3. 确保 target 选项与您的实际运行环境匹配
tsconfig.json
{// TypeScript 编译配置 "compilerOptions": { "target": "ES2020", // 编译目标 "module": "ESNext", // 模块格式 "outDir": "./dist" // 输出目录(后续由 JSShield 混淆) } }

Source Map 说明

JSShield 不支持生成 Source Map。这是一个设计决策——Source Map 会暴露原始代码的结构信息,与代码混淆保护的目的相悖。

建议的调试策略:

  1. 开发环境使用 lowdefault 预设(保留可读性)
  2. 功能测试通过后再切换到 highultimate 预设部署生产
  3. 必要时设置 disableConsoleOutput: false 保留日志输出辅助排查问题

最佳实践

ℹ️ 建议
  • 生产环境推荐使用 highultimate 预设获得最佳保护效果
  • 核心算法/加密逻辑推荐使用 jsvmp 预设获得最高级别的虚拟机保护
  • CI/CD 构建时务必使用内容寻址缓存(基于 hash),避免重复请求浪费配额
  • 本地开发阶段用 low 预设加快构建速度,发布前切高强度
  • 串行处理多个文件—— 并发限制为 1/IP
  • 网络请求设置 60 秒超时防止长时间挂起
  • 绝对不要将令牌提交到公开仓库,统一通过环境变量 JSSHIELD_TOKEN 传入