离线应用锁
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_6377ddb8/softwarelock。
技能介绍
它解决什么问题
把一个 Python 程序(目录、zip 或单个 exe)发给朋友之后,希望它只在那一台机器上跑得起来。常规做法是给每个人发不同密码,或者自己搭一套授权服务器:前者人一多就乱,后者对一个私下分发的小程序来说太重。这个技能走的是「一机一码 + 离线签名」的路子——不联网、不建账号、不发密码,靠硬件指纹和一对 Ed25519 密钥完成绑定。
它是怎么做的
protect.py是一条命令的打包器:把assets/machine_lock.py复制进暂存目录,自动在你那份程序入口顶部注入import machine_lock; machine_lock.gate(),你的源码不会被改动。- 然后用 Nuitka(首选)或 PyInstaller 编译,全程禁用 UPX——UPX 是启发式杀软误报的最大来源。产物只留 exe,不含
.py、不含 token。 - 构建时会生成一对 Ed25519 密钥:公钥烤进 exe,私钥
sl_private_key.pem留在你手上,绝不随分发包发出。同时输出一个与该 build 唯一配对的genkey.exe,就是你双击签激活码的工具。 - 对方首次启动弹出机器码窗口,发给你;你在
genkey.exe里粘贴,拿到激活码回发。exe 用内置公钥验签、确认硬件指纹匹配后写入.sl_token再放行。
激活码绑定的是一组强指纹字段:系统 UUID、主板序列号、BIOS 序列号、第一块磁盘序列号、Windows MachineGuid。CPU/GPU/RAM 序列号被刻意排除——它们在真实机器上经常是空值或不唯一,用了反而会误锁正常用户。如果这些强字段全部读不到(WMI 损坏、沙箱、权限不足),gate() 会直接拒绝,而不是绑一个空指纹悄悄放行。
适用边界与注意点
- 这是「防君子不防小人」的保护。有决心的逆向者仍然能绕过 Python 层检查,Nuitka 和加固只是抬高门槛。
- 只发编译产物,绝不发源码。 对方拿到
machine_lock.py或main.py,删掉那一行gate()就立刻解绑。 - 激活绑定的是硬件指纹而非源码访问,主板或系统盘变更、换机都需要重新申请机器码,且没有迁移或反绑后门。
- 自己跑源码时
gate()会检测到未冻结环境直接放行,方便开发自测;想验证效果可以设SL_SIM_FROZEN=1。 - 默认
SELF_CHECK = True,在核心检查逻辑被削弱或SECRET仍是模板默认值时拒绝启动;建议每次构建用--regen-secret注入新的随机值。
使用场景
- 把自写的 Python 小工具打包成 exe 发给朋友,不想为每个人单独发密码,也不愿搭授权服务器。
- 用 Nuitka 或 PyInstaller 打包后担心杀软误报,需要禁用 UPX 并做 Authenticode 签名压到接近零。
- 想把软件按小时或天数出租,需要离线签发限时激活码,到期后要求对方重新申请机器码。
- 手上只有编译好的成品 exe、不想再改源码,需要用 EXE 融合器把原 exe 加密进壳 exe 并加激活门。
适合人员
- 写了 Python 桌面工具、靠私信逐个发给朋友的独立开发者,希望发出去的 exe 换台机器就跑不起来。
- 负责给公司内部分发自研脚本、又没有预算搭授权服务器的运维或 IT 人员,需要零依赖的离线绑机方案。
- 把 exe 按小时或天数出租的软件作者,需要在不联网的情况下签发限时激活码并核验硬件指纹。
- 手上只有编译好的 exe、没有可改源码,仍想给旧程序补上机器绑定的打包工程师。