Skip to main content

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 .py tù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()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()multiprocessing spawn của app chạy qua launcher mặc định đều có test tích hợp. pkgutil.iter_modules()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.
  • --expires dự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

pyencode_protector-0.3.0.tar.gz (66.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyencode_protector-0.3.0-py3-none-any.whl (53.6 kB view details)

Uploaded Python 3

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

Hashes for pyencode_protector-0.3.0.tar.gz
Algorithm Hash digest
SHA256 56e8bf27b21f66916b943e54dfe3d5ddd18a5c99f754d83587d9a18eb5a333d4
MD5 dab377b897a697cbdfb9b758e60a448e
BLAKE2b-256 4daa08e4aab9c4ab0731b16fb1b3dd898cb3f809a47467a06ceac76ce1e97a95

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyencode_protector-0.3.0.tar.gz:

Publisher: release.yml on VanThanBK/pyencode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyencode_protector-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyencode_protector-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c184c8cfbd90a737a42dc1f076752d1cf07e9ccad4a3135c7b0c9adbb18a29a8
MD5 5b17b96151c682310d69ab8b0a0c3b5e
BLAKE2b-256 24dcbbccbfd22d65980b0869eca39b7a03d4bf728dbd7f22f044d9de9ff17e42

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyencode_protector-0.3.0-py3-none-any.whl:

Publisher: release.yml on VanThanBK/pyencode

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.7.1

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.3.1

2 files

This release

0.3.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page