加密程式碼
protect 與 run、有效期、更強的二因子鎖,以及完全不需要機器鎖的便攜檔。
magiclock protect 能把一個 .py 檔案轉換成 .pya——一個加了閘門的加密容器——不需要編譯器,也不會把你的原始碼上傳到任何地方。magiclock run 負責執行它。
基本用法
# First run: signs you in and activates this machine, then encrypts.
# Every encrypt after that is instant and non-interactive.
magiclock protect app.py # -> app.pya
magiclock run app.pya
# Point at a directory to protect a whole project tree recursively
# (.venv/venv/__pycache__/.git/dist/build are skipped automatically).
magiclock protect src/.pya 檔案就是普通檔案,你可以像現在發布應用程式一樣提交、複製或打包它——加密效果會隨檔案一起走。
運作原理
.pya 是一個帶版本號的小型容器,裡面包著一個加密信封。magiclock run app.pya 會在記憶體中將它解密,為它匯入的所有內容安裝一個 import 掛鉤,然後執行——任何明文都不會被寫回磁碟。因為裡面的封裝位元碼與加密它的 CPython 版本綁定,Python 3.12 加密出來的 .pya 無法在 3.13 上載入;升級直譯器後重新執行一次 protect 即可。
刪除明文
magiclock protect app.py --remove # encrypt, then delete app.py有效期:限時與自毀產物
以下旗標會把有效期直接戳進加密產物本身——獨立於你的授權——過期後該產物會拒絕解密:
magiclock protect app.py --expires-in 30d # stops decrypting in 30 days
magiclock protect app.py --expires-at 2026-12-31 # stops decrypting on a date
magiclock protect app.py --trial # fixed 48-hour self-destruct — for demos and evaluations--trial、--expires-in 與 --expires-at 彼此互斥——每個檔案只能擇一使用。
更強:二因子鎖(機器+密碼片語)
預設情況下,產物只需要在對的機器上就能解密。加上一個密碼片語作為第二因子:
magiclock protect app.py --lock-passphrase
# prompts for a passphrase (or reads $MAGICLOCK_PASSPHRASE non-interactively)
magiclock run app.pya --passphrase便攜檔:完全不綁定機器
有時你需要一個產物能在你尚未啟用過的機器上執行——客戶的機器,或是你管不到的機器。便攜模式會拿掉機器鎖,改用共享密鑰解鎖——強度較弱,但可以自由散布:
# Passphrase-protected, no machine lock:
magiclock protect app.py --no-bind-machine --passphrase
magiclock run app.pya --passphrase
# Or hand out a generated key instead of a passphrase:
magiclock protect app.py --no-bind-machine --emit-key
magiclock run app.pya --key <the-printed-key>--lock-passphrase 與便攜相關旗標(--no-bind-machine、--passphrase、--emit-key)彼此互斥——一個產物要麼是機器鎖定的(可選擇加上密碼片語作為第二因子),要麼是便攜的(靠密碼片語/金鑰解鎖,而非機器身分),兩者不能同時成立。
在 CI 或腳本化執行中,密碼片語與便攜金鑰都可以從環境變數讀取,而不必透過提示輸入:
export MAGICLOCK_PASSPHRASE=... # for --lock-passphrase or portable --passphrase artifacts
export MAGICLOCK_DECRYPT_KEY=... # alternative to `run --key` for --emit-key artifacts
magiclock run app.pya