加密你的代码
protect 与 run、有效期,以及五档保护级别——从可自由分发的免密钥产物到机器锁定的二因子保险库。
magiclock protect 把一个 .py 文件变成 .pya——一个加了闸门的加密容器——不需要编译器,也不会把你的源码上传到任何地方。magiclock run 负责运行它。
基本用法
# 首次运行:登录并激活这台机器,然后加密。
# 之后每次加密都是瞬时完成、无需交互。
magiclock protect app.py # -> app.pya
magiclock run app.pya
# 指向一个目录即可递归保护整个项目树
# (.venv/venv/__pycache__/.git/dist/build 会被自动跳过)。
magiclock protect src/.pya 就是普通文件,你可以像现在分发应用一样提交、拷贝或打包它——加密效果随文件一起走。默认产物是免密钥便携的:任何装了 magiclock 的机器都能透明解密它,运行侧不需要账号、不需要口令、也没有机器锁。因此默认档属于便利/混淆级保护——你的源码不会以明文出货,但任何拿到文件且装了运行时的人都能执行它。需要真正的访问控制时,请在下面选择更强的级别。
选择保护级别
| 级别 | 参数 | 谁能解密 |
|---|---|---|
| 免密钥便携*(默认)* | (无) | 任何装了 magiclock 的人——便利/混淆级。 |
| 口令便携 | --passphrase | 任何知道口令的人,在任何机器上。 |
| 密钥便携 | --emit-key | 任何持有生成密钥的人,在任何机器上。 |
| 机器锁定 | --bind-machine | 只有这台已激活的机器——不可导出的机器密钥加授权闸门;最强的单因子级别。 |
| 机器 + 口令 | --bind-machine --passphrase | 这台已激活的机器加上口令——二因子。 |
工作原理
.pya 是一个带版本号的小容器,里面包着一个加密信封。magiclock run app.pya 会把它在内存中解密,为它 import 的所有内容安装一个 import 钩子,然后执行——任何明文都不会被写回磁盘。因为里面的字节码和加密它的 CPython 版本绑定,Python 3.12 加密出的 .pya 不能在 3.13 上加载;升级解释器后重新 protect 一次即可。
删除明文
magiclock protect app.py --remove # 加密后删除 app.py有效期:限时与自毁产物
以下参数把有效期直接戳进加密产物本身——独立于你的授权——过期后该产物拒绝解密:
magiclock protect app.py --expires-in 30d # 30 天后停止解密
magiclock protect app.py --expires-at 2026-12-31 # 到指定日期后停止解密
magiclock protect app.py --trial # 固定 48 小时自毁——用于演示与评估--trial、--expires-in、--expires-at 三者互斥,每个文件只能选一个。
带密钥的便携档:口令或密钥
免密钥的默认档对运行产物的人没有任何要求。想保留便携性、同时加一道访问密钥,从两种便携模式里选一个:
# 口令保护,仍可在任何机器上运行:
magiclock protect app.py --passphrase
magiclock run app.pya --passphrase
# 或者分发一个生成好的密钥而不是口令:
magiclock protect app.py --emit-key
magiclock run app.pya --key <打印出来的密钥>--passphrase 与 --emit-key 互斥——每个产物只能选一种密钥。
最强:机器锁(--bind-machine)
当产物完全不允许离开你的机器时,把它绑定到这台已激活的机器——解密需要这台机器上不可导出的保险库密钥并通过授权闸门,文件拷到任何别的地方都没有用:
magiclock protect app.py --bind-machine
magiclock run app.pya # 只能在加密它的那台机器上运行再叠加一个口令即为二因子锁——既要对的机器,又要口令:
magiclock protect app.py --bind-machine --passphrase
# 交互式提示输入口令(或非交互读取 $MAGICLOCK_PASSPHRASE)
magiclock run app.pya --passphrase--emit-key 只用于便携档,与 --bind-machine 互斥——机器锁定产物的密钥永远不会离开那台机器,本来就没有可分发的东西。
在 CI 或脚本化运行中,口令和便携密钥都可以从环境变量读取,而不必交互输入:
export MAGICLOCK_PASSPHRASE=... # 用于 --passphrase 产物(便携或二因子)
export MAGICLOCK_DECRYPT_KEY=... # --emit-key 产物中 `run --key` 的替代方式
magiclock run app.pya