PyEncode
PyEncode là công cụ bảo vệ ứng dụng CPython thuần Python, hướng tới Windows và
Linux. Mỗi module được biên dịch thành code object, tuần tự hóa bằng marshal,
nén rồi mã hóa xác thực bằng AES-256-GCM. Runtime giải mã và thực thi trong bộ
nhớ; source và bytecode rõ không được ghi ra file tạm.
Phiên bản 0.3 dùng định dạng PYE2:
- Mỗi artifact có tên ngẫu nhiên 128 bit, ví dụ
myapp/7b82a40e9aa14e60db7094f2de3fbc33.pye. - PYE2 không có header JSON rõ; file chỉ chứa magic, nonce và ciphertext/tag.
- Tên module, entry point và cờ package nằm trong một module index được mã hóa.
- Manifest format 3 được ký Ed25519 và chứa hash SHA-256 của artifact.
- Runtime, launcher, resource và support tree do builder sao chép đều được ký,
key-bind và kiểm tra lại lúc
install(). - Loader chỉ trả một trampoline nhỏ cho
runpy, không trả code object thật của ứng dụng. Khóa module được dẫn xuất theo nhu cầu và không giữ trong finder.
Mục tiêu là tăng đáng kể chi phí phân tích so với .pyc, không phải tạo cơ chế
chống reverse tuyệt đối.
Python được hỗ trợ
PyEncode 0.3 yêu cầu CPython chuẩn 3.10 trở lên. CI kiểm thử trực tiếp các phiên bản 3.10 đến 3.15; các CPython feature release mới hơn được phép cài và build theo hướng forward-compatible, rồi được đưa vào ma trận bắt buộc sau khi có bản phát hành và dependency wheel tương ứng. PyPy và các interpreter khác hiện chưa được hỗ trợ.
Runtime là Python thuần nên cùng source runtime dùng được trên Windows và Linux. Tuy nhiên artifact đã build gắn với đúng CPython major/minor:
- build bằng CPython 3.11 → chạy bằng CPython 3.11;
- không chạy artifact đó bằng 3.10, 3.12 hoặc 3.14;
- muốn phát hành cho nhiều minor version, build một output bằng từng interpreter.
Nếu bundle có thêm .pyd, .so, .dll hoặc dependency native qua --support,
toàn bundle còn phụ thuộc hệ điều hành, kiến trúc và ABI của các file đó. Phạm
vi kiểm thử hiện tại là CPython GIL tiêu chuẩn; free-threaded/debug ABI cần build
và kiểm tra riêng.
Cài đặt
Sau khi package được phát hành trên PyPI, cài bằng:
py -3.11 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install pyencode-protector
Tên lệnh CLI và import namespace vẫn là pyencode.
Để phát triển trực tiếp từ source, cài editable trong virtual environment:
Windows PowerShell:
py -3.11 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e .
Linux:
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .
Dependency runtime duy nhất là cryptography>=42.
Sử dụng
Bảo vệ một file:
pyencode build hello.py -o dist/hello
python dist/hello/run.py
Bảo vệ package có __main__.py:
pyencode build src/myapp -o dist/myapp
python dist/myapp/run.py
Chỉ định entry module:
pyencode build src -o dist/app --entry myapp.__main__
Ký và key-bind thêm dependency/support tree:
pyencode build src -o dist/app \
--entry myapp.main \
--support build/vendor _vendor \
--support public/config.json config.json
--support SOURCE DEST có thể lặp lại. Nếu SOURCE là thư mục, nội dung cây
được chép dưới DEST; nếu là file, DEST là đường dẫn file đầu ra. Symlink,
reparse point, đường dẫn thoát root và va chạm chữ hoa/thường bị từ chối.
Đích chính xác _vendor được xem là bootstrap dependency path cho host không
có cryptography cài sẵn (như Fusion). Chỉ đúng entry _vendor trong
sys.path được giữ lúc verifier nạp; mọi đường dẫn con khác trong bundle bị
cách ly. Vì thư viện mật mã vendored phải chạy trước khi Ed25519 có thể tự kiểm
chứng bundle, _vendor là một phần bootstrap được tin cậy theo thiết kế của
runtime Python thuần; chỉ đóng gói wheel lấy từ nguồn tin cậy.
Các tùy chọn chính:
-o,--output: thư mục output; phải chưa tồn tại hoặc hoàn toàn rỗng.-e,--entry: dotted name của entry module/package.--exclude GLOB: loại đường dẫn khớp glob; có thể lặp.--no-resources: không sao chép file không phải Python trong source tree.--keep-docstrings: giữ docstring.--optimize {0,1,2}: mức tối ưu CPython.--expires YYYY-MM-DD: từ chối chạy sau ngày UTC đã cho.--launcher PATH: dùng launcher.pytùy biến.--support SOURCE DEST: sao chép, ký và key-bind file/cây hỗ trợ.--rename-locals: đổi tên metadata của local không phải tham số.--allow-extra-data: cho host tạo thêm file/thư mục dữ liệu không thực thi; file đã ký và Python/native artifact lạ vẫn bị kiểm tra.
--rename-locals là opt-in vì code dùng alias động của locals(), đọc
frame.f_locals, debugger hoặc một số framework introspection có thể cần tên
local gốc. Argument, closure, line table và exception table luôn được giữ.
Launcher tùy biến và host nhúng
Launcher được sao chép nguyên byte, ký và tham gia dẫn xuất khóa. Nó phải đặt:
import sys
sys.dont_write_bytecode = True
trước mọi import không phải bootstrap. Builder kiểm tra điều kiện tối thiểu này.
Một launcher ship an toàn cũng phải kiểm tra pyencode_runtime không chứa
__pycache__, .pyc hoặc file lạ trước khi import package; launcher mặc
định và pipeline Weldments đã có preflight đầy đủ.
Host như Fusion có thể nạp entry mà không ghi tên module rõ trong stub:
import sys
sys.dont_write_bytecode = True
# Thực hiện preflight pyencode_runtime tại đây.
from pyencode_runtime import load_entry
implementation = load_entry()
install() cố ý trả None. load_entry() trả module entry cho embedding host;
run() thực thi entry với ngữ nghĩa __main__.
Output
dist/app/
├── .pyencode-manifest.json
├── myapp/
│ ├── 14a0...f91c.pye
│ ├── 7b82...bc33.pye
│ └── assets/config.json
├── pyencode_runtime/
│ ├── __init__.py
│ ├── _build.py
│ ├── _mp_main.py
│ └── _runtime.py
├── requirements.txt
└── run.py
Resource không được mã hóa, nhưng byte/path của resource build-time được ký và key-bind. Mặc định toàn bộ cây output là bất biến: runtime từ chối mọi file hoặc thư mục được thêm, xóa hay đổi byte.
Với host tự tạo metadata/cache cạnh add-in, --allow-extra-data cho phép thêm
file và thư mục dữ liệu mà không làm bundle chết. Chế độ này không cho sửa/xóa
file đã ký, không cho thêm .py, .pyc, native library hoặc .pye lạ, và vẫn
từ chối symlink/reparse point. Không dùng data bổ sung này làm đầu vào tin cậy
cho license hay quyết định bảo mật. Pipeline Weldments bật chế độ tương thích
này để Fusion có thể tạo .vscode, log hoặc cache khác nhau giữa các máy.
__file__ của protected module là đường dẫn thật tới artifact ngẫu nhiên. Vì
vậy Path(__file__).parent, pkgutil.get_data() và importlib.resources kể cả
resource lồng thư mục vẫn hoạt động; code phụ thuộc basename/stem của
__file__ sẽ thấy token ngẫu nhiên.
Import theo fullname, relative import, circular import, namespace package,
Unicode module, reload, runpy.run_module() và multiprocessing spawn của app
chạy qua launcher mặc định đều có test tích hợp. pkgutil.iter_modules() và
walk_packages() không thể tự khám phá tên protected child vì tên đó cố ý nằm
trong index mã hóa; import theo fullname đã biết vẫn hoạt động.
Với embedding host gọi load_entry(), spawn hoạt động nếu child cũng chạy lại
bootstrap của host. Trường hợp host chỉ bootstrap bên trong
if __name__ == '__main__' rồi spawn trực tiếp một target protected cần launcher
riêng; bootstrap spawn tự động hiện tập trung vào app chạy qua run().
Phiên bản 0.3 dùng một namespace runtime cố định trong mỗi process. Không nạp hai distribution PyEncode độc lập vào cùng một interpreter; chạy chúng ở hai process riêng. Runtime namespace ngẫu nhiên/đa-bundle là hạng mục tương thích trước khi công bố API ổn định 1.0.
Giới hạn bảo mật
PyEncode làm khó phân tích tĩnh nhưng không thể giữ bí mật tuyệt đối trên máy do người khác toàn quyền kiểm soát:
- Chế độ mặc định là offline nên key material vẫn phải nằm trong bundle. Người có kinh nghiệm có thể đọc runtime và tái tạo quá trình dẫn xuất khóa.
- Code object phải xuất hiện trong bộ nhớ khi thực thi. Tracing, debugger, monkeypatch hoặc hook native vẫn có thể quan sát code/runtime state.
- Integrity interlock chặn sửa file, tráo artifact, chèn code và re-sign đơn giản; nó không biến Python thuần thành trust anchor native.
- Tên module/entry được che khi nằm yên, nhưng xuất hiện lúc import trong
sys.modules, traceback và runtime state. Thư mục package/resource vẫn có thể tiết lộ một phần cấu trúc. --expiresdựa trên đồng hồ hệ thống và không thay thế hệ thống license.
Đừng đặt API key/private key dài hạn trong client. Bước nâng cấp tạo khác biệt bảo mật thực sự cho sản phẩm giá trị cao là external/envelope key lấy từ license server hoặc keyring; native runtime chủ yếu tăng thêm chi phí phân tích.
Kiểm thử
python -m unittest discover -v
CI chạy trên Windows và Ubuntu với CPython 3.10–3.15. Bộ test bao phủ PYE2,
module index mã hóa, KDF vectors, tamper/re-sign, resource/support integrity,
opaque filenames, import/package/namespace/Unicode, runpy, multiprocessing
spawn, launcher thường không có -B, policy hết hạn và output atomic.
Phát hành
Quy trình phát hành production bằng GitHub OIDC được ghi tại
RELEASING.md. Workflow chỉ upload lên PyPI khi push tag khớp
chính xác version, ví dụ v0.3.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyencode_protector-0.3.0.tar.gz.
File metadata
- Download URL: pyencode_protector-0.3.0.tar.gz
- Upload date:
- Size: 66.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56e8bf27b21f66916b943e54dfe3d5ddd18a5c99f754d83587d9a18eb5a333d4
|
|
| MD5 |
dab377b897a697cbdfb9b758e60a448e
|
|
| BLAKE2b-256 |
4daa08e4aab9c4ab0731b16fb1b3dd898cb3f809a47467a06ceac76ce1e97a95
|
Provenance
The following attestation bundles were made for pyencode_protector-0.3.0.tar.gz:
Publisher:
release.yml on VanThanBK/pyencode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyencode_protector-0.3.0.tar.gz -
Subject digest:
56e8bf27b21f66916b943e54dfe3d5ddd18a5c99f754d83587d9a18eb5a333d4 - Sigstore transparency entry: 2529924781
- Sigstore integration time:
-
Permalink:
VanThanBK/pyencode@0d71ee7467c143f315903fbe7020d4c521d5dc25 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/VanThanBK
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0d71ee7467c143f315903fbe7020d4c521d5dc25 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyencode_protector-0.3.0-py3-none-any.whl.
File metadata
- Download URL: pyencode_protector-0.3.0-py3-none-any.whl
- Upload date:
- Size: 53.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c184c8cfbd90a737a42dc1f076752d1cf07e9ccad4a3135c7b0c9adbb18a29a8
|
|
| MD5 |
5b17b96151c682310d69ab8b0a0c3b5e
|
|
| BLAKE2b-256 |
24dcbbccbfd22d65980b0869eca39b7a03d4bf728dbd7f22f044d9de9ff17e42
|
Provenance
The following attestation bundles were made for pyencode_protector-0.3.0-py3-none-any.whl:
Publisher:
release.yml on VanThanBK/pyencode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyencode_protector-0.3.0-py3-none-any.whl -
Subject digest:
c184c8cfbd90a737a42dc1f076752d1cf07e9ccad4a3135c7b0c9adbb18a29a8 - Sigstore transparency entry: 2529924934
- Sigstore integration time:
-
Permalink:
VanThanBK/pyencode@0d71ee7467c143f315903fbe7020d4c521d5dc25 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/VanThanBK
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0d71ee7467c143f315903fbe7020d4c521d5dc25 -
Trigger Event:
push
-
Statement type: