swcenc 加密器 · 离线加密器发行与授权中心
客服邮箱 admin@xueyuanpie.com

swcenc 2.0.0 发布说明

交付日期:2026-10-08

标题:Swoole 官方同款离线加密器 —— 自带运行时(零依赖)+ 授权绑定 + 产物域名/到期绑定


一、这次交付了什么

交付物位置说明
Windows 安装包dist/swcenc-2.0.0-win64-setup.exe(43MB)双击安装:桌面/开始菜单快捷方式、卸载项、装完可直接跑自检
Windows 免安装包dist/swcenc-2.0.0-win64.zip(72MB,解压 145MB)解压即用,运行 bin\swcenc.exe
Linux 发行包dist/swcenc-2.0.0-linux-x86_64.tar.gz(204MB,解压 511MB)自带 Python + PHP 7.0–8.4 + glibc 与全部依赖库
对外下载页<https://jiamiqi.xueyuanpie.com/>两个包 + sha256,静态直出
授权签发工具tools/licgen.py + license/private_key.pem只在签发者手里,不进发行包
引擎侧新能力线上引擎 engine/pack/授权模块 / 绑定层 / 内置运行时探测

下载校验(与本地一致,已实测回下载比对):

linux         5b2cc51a3d0ac7f350dd7c804658479313da93a0f8eb99bd7cb42921186869f7
win setup.exe e4d16047738b9c6693c9d73a040243c0a774cabbb03db29f3159d1e3899eb403
win portable  bd7184f40fb010970cb08d58a7a9f967112085cc84b8a18b6a41ad0eb244cca0

一之二、发行包里没有源码(本轮新增)

两条硬要求,都已落实:

要求LinuxWindows
不发 Python 源码引擎 12 个模块全部 Cython 编译成 .so(原生机器码),包里 .py 数 = 0引擎编译成 .pyc 字节码(无 .py),再打进安装包与便携包
授权校验写进编译产物swc_license 编译进 .so,且 ENFORCED_BY_BUILD 在构建时烘焙为 True同样烘焙后再编译成 .pyc

烘焙的效果(已实测):

SWCENC_ENFORCE=0 ./bin/swcenc pack ... —— 照样被授权拦住。

也就是说"要不要校验授权"这件事只存在于编译产物里,客户既改不了(没有源码),也绕不过(环境变量被构建常量压过)。

线上服务用的是同一份引擎源码,其 ENFORCED_BY_BUILD 保持 False,不受影响。

构建流程:tools/build_dist_engine.py(复制源码到临时目录 → 烘焙 → Cython/字节码编译 → 自检),

build2.sh 调用它。编译产物自身会先跑一次 versions 自检,编译过了但导入就炸的情况不会流到发行包。


一之三、发行包完整性修复(本轮实测抓出来的两个真问题)

两个都是"能出产物、但少了一层保护"的静默失效,靠 Alpine 里真跑一遍才暴露:

#现象根因修法
1--pro 在发行包里直接报 No module named 'parse_oparray'(普通 strong 却正常)构建脚本算 rev 的源码目录时把临时工作目录当成了引擎目录(<tmp>/../rev = /tmp/rev),文件不存在又被 isfile 静默跳过 —— 发行包里从来没有 rev/parse_oparray改成显式传 rev 源码目录;并把"逐个模块真的 import 一遍"加进构建自检(少一个模块直接构建失败)
2--pro(默认 --scatter full)打散层完全没生效,日志里只有一句不起眼的"scatter 跳过"swc_scatter.php / swc_symbols.php 要 require __DIR__.'/vendor/autoload.php'(nikic/php-parser),而发行包没带 vendor/把 vendor/(1.9MB,273 个文件,BSD-3)打进两个平台包;build2.sh 的资产拷贝与构建体检都加上它;引擎侧的跳过提示改成显眼的 ⚠ scatter 未生效(缺 vendor/php-parser?…)

修复前后(同一个包、同一条命令、Alpine 里实测,用 SWCENC_LAYER_REPORT 读结构化层清单):

修复前  --scatter full  ->  scatter: {}
修复后  --scatter full  ->  scatter: {mode: full, strings: 4, renamed: 0, seed: 603ce30d, ...}
        --pro           ->  scatter: {...full...}  +  pro: {ops_permuted: 41/41}  +  guard: on
        --pro --php 8.3 --verify  ->  [验证] 真实 loader 加载执行通过

第 1 条还顺手把引擎的 probe_strict() 修准了:Windows 上 rev/opdump 里是 Linux 的 .so,

php.exe 根本加载不了,以前只判断"文件在不在",于是会拿着它去 dump 再报一句

"opdump 没有产出数据"。现在 Windows 直接判定"无转储扩展",能力矩阵如实反映、

--swc-strict/--pro 报的是真正的原因。

这两条是发行包的问题,线上 swcapi.xueyuanpie.com 一直是好的(源码 + 完整的 rev/vendor 都在),
所以线上行为没有任何变化 —— 复检 act=versions 仍返回全部 10 个 PHP 版本。

实测支持矩阵(发行包 + 真实 loader,逐个组合跑 --verify)

目标 PHPloader 3.1loader 3.2
7.0 / 7.1 / 7.2❌ 段错误❌ 段错误
7.3 / 7.4✅✅(--swc-strict 通过)
8.0 / 8.1✅✅
8.2 / 8.3 / 8.4—(官方 3.1 无这些版本)✅(--pro 在 8.3 实测通过)

已知限制(引擎本身,线上与发行包一致)

  • PHP 7.0 / 7.1 / 7.2 的产物会在加载时段错误(实测 PHP 7.0.33 / 7.1.33 / 7.2.33,

loader 3.1 与 3.2 都一样;带/不带 opcache 一样;线上 swcapi 用同一份引擎复现完全相同)。

所以:目标请用 7.3+;确实要交付 7.0–7.2,请先在目标机上用小文件试一次。

这是引擎的既有问题,与本次(Swoole/SG 解密、离线加密器)的改动无关,本轮未动它。

  • --swc-strict / --pro 在 7.0 / 7.1 上会 fail-closed 直接报错

(引擎拒绝产出被弱化的"PRO 产物",而不是静默降级)。

  • Windows 上 --pro / --swc-strict 只支持 PHP 7.0/7.1(7.2+ 需要 Linux 专有的转储扩展),

见 USAGE.md 的能力对照表。


一之四、引擎全部原生化 + 自解密容器(本轮)

核心全部是机器码,外面只留"第一个调用":

平台引擎入口外面那层壳
Linux14 个 Cython .soengine/libswcenc.so(导出 swcenc_main)bin/swcenc(37 行 shell)+ bin/swcenc.bin(40 行 C,只做 dlopen+调用)
Windows14 个 .pyd(mingw 交叉编译 + 官方 python312.dll)自带 python.exebin\swcenc.exe(原生启动器)
  • Windows 从 .pyc 换成 .pyd(真机器码):交叉编译 → 静态自检(PE / PyInit_ 导出 /

依赖 python312.dll)→ 在 Wine 里真跑:14/14 模块导入成功、pack 出产物,

产物再用 Linux 侧真实 swoole_loader 执行得到 WIN-OK。

  • 核心 PHP 助手加密随包:swc_pathfix.php / swc_scatter.php / swc_symbols.php

变成 .enc(HMAC-SHA256 计数器流 + 认证标签),运行时解密到同目录、用完删除,

密钥烘焙在编译产物里 —— 包里既没有明文也没有可读源码。

  • 自解密容器(phpshield):4 套 loader(34 个)、rev/opdump(11 个)、引擎入口已加固。

已知边界:phpshield 是"一个进程一个壳"的设计,Python 引擎一次加载 14 个模块,

实测只有第一个能加载,所以 Python 模块保持 Cython 机器码(包内 .py/.pyc 仍为 0)。

  • 水印改在原生模块里:wm.so / wm.pyd 的三段占位串按用户等长替换,

启动横幅打印归属(实测:本副本仅授权给下列账号使用:tester01 …)。

本轮实测

Linux(Alpine,无 glibc/PHP/Python)
  doctor / license / pack --php 8.3 --scatter full --verify
  → [验证] 真实 loader 加载执行通过        水印横幅正常打印
  engine/*.py = 0,核心 .php 明文 = 0,.enc = 3

Windows(Wine,首次真机级验证)
  14/14 个 .pyd 导入成功
  pack --php 8.4 → 产物 1912 字节
  Linux 侧真实 swoole_loader 执行该产物 → WIN-OK:wine

二、三个核心能力

1. 零依赖(自带运行时)

组件LinuxWindows
解释器自带 CPython 3.12(只带标准库,引擎只用标准库)自带免安装 Python 3.12
PHP自带 7.0–8.4 的 php + 各版本 opcache.so自带官方 NTS x64 的 php.exe + php8.dll(7.x 为 php7.dll) + ext/php_opcache.dll
系统库自带 glibc + 63 个依赖 .so,用自带 ld-linux 启动自带 vcruntime140*.dll(VC14 族二进制兼容 VS2015–2022)

实测证据:把一个「没有 glibc、没有 PHP、没有 Python」的 alpine:3.20 容器里跑完整流程 ——

doctor / license / pack --verify(PHP 8.3 与 7.4 各一次)/ 产物在官方 loader 下执行,全部通过。

为什么这么打包:引擎(连 swcopdump*.so 转储扩展)本来就是针对这套 PHP 构建验证过的,

换成自编译 PHP 等于把 ABI / opcache file_cache 兼容性重新赌一次;闭包方案的依赖是自带的,

零依赖目标一样达成,而且不会引入新的兼容性风险。

2. 授权绑定(机器码 / 有效期 / 版本权益)

  • 签名:RSA-2048 + SHA-256 + PKCS#1 v1.5,纯标准库实现(工具侧无需任何第三方库)
  • 校验顺序(报错都能直接指导客户下一步):签名 → 有效期 → 机器码 → 功能位
  • 机器码:Linux = 系统 id + 首块物理网卡 MAC + CPU 型号;Windows = MachineGuid + 系统卷序列号 + MAC
  • 版本权益:trial / std / pro / enterprise 决定 strong / batch / pro / bind / decoy 功能位

实测的四类拒绝(都给了可执行的中文提示):

篡改内容   → 授权文件签名校验失败:内容被改动过,或不是本产品签发的文件…
过期       → 授权已于 2024-02-01 过期(过期测试)。请凭本机机器码 SWC-… 联系签发者续期。
换机器     → 该授权不适用于本机:授权绑定的是 SWC-0000-1111-2222,本机是 SWC-655E-0CC9-0961…
功能位不足 → 当前授权不含「Pro 虚拟机层(--pro)」(标准版)。…请联系签发者升级授权。

3. 产物绑定(域名 / IP / 到期)

./bin/swcenc batch ./app -o ./app_enc --php 8.3 \
    --domains "customer.com,*.customer.com" --ips "1.2.3.4" --expire 2027-01-01

行为(三条都是刻意设计,避免售后灾难):

  • 域名 / IP 只拦 Web,CLI 默认放行(否则客户 cron / 队列会集体挂掉);要一并绑加 --bind-cli
  • 到期是绝对的:Web 与 CLI 都拦
  • 域名支持通配前缀 *.example.com,且同时匹配 apex 域

实测(php -S + 真 loader):

Host: example.com       → 200  42
Host: sub.example.com   → 200  42          (通配命中)
Host: evil.com          → 403  This script is not licensed to run here (host evil.com).
过期产物(CLI 直跑)     →      This script is not licensed to run here (expired on 2020-01-01).

绑定层与源码一起被编译进载荷,不是可读配置。


三、怎么签发授权

cd /root/swcenc
python3 tools/licgen.py machine                       # 签发者本机机器码
python3 tools/licgen.py sign \
    --customer "某某科技" --edition pro \
    --machines SWC-XXXX-XXXX-XXXX \
    --domains "customer.com,*.customer.com" \
    --months 12 --out license-xxx.json
python3 tools/licgen.py show license-xxx.json         # 校验(含机器码/有效期)

把 license-xxx.json 改名成 license.json 交给客户,放进发行包 license/ 目录即可。

  • 私钥:license/private_key.pem(0600,不要外发、不要进包)
  • 换密钥 = 所有老授权失效,所以换之前要给所有客户重签
  • 客户机换机器 / 授权到期 → 拿新机器码重签一份即可

四、验证清单(本次实际跑过的)

验证结果
编译版(.so)引擎在无 glibc/PHP/Python 容器里跑通✅ license / doctor / pack --verify / 产物执行 全通过
环境变量绕过授权✅ SWCENC_ENFORCE=0 仍被拦(烘焙生效)
发行包源码体检✅ Linux:engine/**/*.py = 0,.so = 12;Windows:.py = 0,.pyc = 12
Windows 安装包载荷✅ 用 7z 解出 207 个文件,含 bin/swcenc.exe、.pyc、两代 loader、10 个 PHP;无 .py、无私钥、无 license.json
无 glibc/PHP/Python 容器里 doctor✅ 内置运行时被识别,10 个 PHP 版本全绿
同一容器里 pack --verify(PHP 8.3 / loader 3.2)✅ 真实 loader 加载执行通过
同一容器里 PHP 7.4 / loader 3.1✅ 通过
产物在容器里用官方 loader 执行✅ 输出正确
未授权打包✅ 退出码 3 并给出机器码
篡改 / 过期 / 他机 / 功能位不足✅ 四类全部正确拒绝
域名绑定(通配/非法/CLI)✅ 200 / 200 / 403 / CLI 放行
到期绑定(CLI 也拦)✅ 拒绝并给出到期日
线上服务回归(网关 → swcapi → 引擎 → 产物)✅ 加密成功、产物正常
公开下载 URL + sha256 回下载比对✅ 一致

Windows 包:结构层面已验证(swcenc.exe 为 PE32+ 控制台程序、安装包为 NSIS PE、

载荷 207 个文件齐全、.py = 0),但本机没有 Windows 也没有 Wine,没有真机执行过。

Windows 侧三个需要你在真机上确认的点:

  • swcenc.exe doctor —— 应打印内置运行时(10 个 PHP 版本)与授权状态;
  • 菜单里选 3) 加密单个文件 —— 应能出产物;
  • 装完在「程序和功能」里能看到 swcenc,卸载后目录与快捷方式都清掉。

五、已知限制 / 待办

  • Windows 未真机验证(本机既无 Windows 也无 Wine,只做了结构校验:PE32+ 启动器、

NSIS 安装包、载荷 210 个文件齐全、.py = 0)。第一台 Windows 机器上请按顺序确认:

① 双击安装 → 桌面出现「swcenc 加密器」;② "%LOCALAPPDATA%\swcenc\bin\swcenc.exe" doctor

应列出内置的 10 个 PHP 版本与授权状态;③ 菜单选 3) 加密单个文件(PHP 8.3)应出产物并自报

[完成];④ 卸载后目录与快捷方式清干净。

--verify 在 Windows 上按设计跳过(loader 是 Linux 扩展),

--pro / --swc-strict 在 Windows 上只支持 PHP 7.0/7.1。

需要逐次验证或 Pro 层的产物,请在 Linux 机器上打包。

  • 容器里机器码不稳定:机器码含网卡 MAC,容器重建即变。建议装在固定物理机 / VPS。
  • swcapi.xueyuanpie.com 的 data/version_matrix.json 缓存被写空过一次(引擎文件权限问题导致

引擎读不进来)。已修:新增模块的属主/权限已对齐 www:www 644,并加固了缓存逻辑 ——

引擎临时不可用时沿用上一次的好数据,不再写空矩阵(否则客户会看到

「loader 3.2 不支持 PHP 8.3」)。

  • cj.xueyuanpie.com 的 PHP 应用本身在 500(与本次交付无关,静态文件不受影响)。
  • 包体积较大(Linux 505MB 解压)源于自带 10 个 PHP 版本 + glibc 闭包。若客户只要一两个

PHP 版本,可以出一个精简包(改 runtime/build_runtime_linux.py 的版本列表重打包即可)。

文档为随发行包一起提供的原文(docs/RELEASE-2.0.0.md)。 下载发行包后可离线查看同样的内容。