核心概念:什麼是 PyArmor?

PyArmor 是一個專門用來「混淆」(Obfuscate)Python 程式碼的第三方函式庫和命令列工具。混淆的目的是讓原始程式碼變得極難閱讀和理解,從而保護您的商業邏輯與智慧財產權。值得注意的是,Python 是一種「直譯式語言」,其混淆技術主要是增加破解的門檻,其安全性無法與 C++ 這類「編譯式語言」相比。

重要安全觀念提醒

絕對不要在程式碼中儲存明文密碼! 即使是混淆過的檔案,有心人士依然可能找到寫死的字串。請將敏感資訊儲存在環境變數或金鑰管理服務中。PyArmor 只是提高破解門檻,並非萬無一失的安全解方。

主要功能與特色

🛡️ 程式碼混淆

將 `.py` 檔案轉換為人類難以閱讀的格式,隱藏原始變數、函式名稱和字串。

📅 設定有效期限

可為程式設定到期日,適合發布試用版軟體。

💻 硬體綁定

將程式綁定到特定硬體(如 MAC 位址)上執行,防止非法複製。

📦 打包成執行檔

整合 PyInstaller,將所有檔案打包成單一執行檔,方便發布。

程式碼混淆 vs. 程式碼編譯

了解 Python 的程式碼混淆與 C/C++ 等語言的編譯在本質上的不同之處,有助於設定合理的安全預期。

特性Python 程式碼混淆 (使用 PyArmor)C/C++ 程式碼編譯
保護程度較低。旨在增加閱讀難度,但理論上仍可被逆向工程還原。較高。程式碼被編譯成機器碼,逆向工程的技術門檻非常高。
運作原理將程式碼轉換為不易讀的格式,執行時透過擴充模組動態解譯給 Python 直譯器。將程式碼直接翻譯成 CPU 能執行的二進位機器語言。
執行環境仍需 Python 直譯器環境(除非使用打包功能)。直接在作業系統上執行,不需額外解譯器。
最終產物混淆後的 `.py` 檔案和一個必要的擴充模組。單一的可執行檔(如 `.exe`)。

基本使用方法

1. 安裝 PyArmor

透過 `pip` 套件管理工具即可安裝。

pip install pyarmor

2. 檢查版本

由於新舊版本指令不同,建議先檢查您安裝的版本。

pyarmor --version

3. 執行混淆指令

在 PyArmor 8.x 及更新版本中,請使用 `gen` 指令。執行後,PyArmor 會建立一個名為 `dist` 的資料夾。

pyarmor gen 你的腳本名稱.py

版本差異說明

- PyArmor 8.x / 9.x (新版): 使用 `gen`、`generate` 或 `g` 指令。
- PyArmor 7.x (舊版): 使用 `obfuscate` 指令。

4. 執行混淆後的程式

混淆後的程式碼需要依賴 `dist` 資料夾中的擴充模組才能執行。

python dist/你的腳本名稱.py

注意:若要發布,必須將 `dist` 資料夾中的所有檔案(包含一個名為 `pyarmor_runtime_000000` 的執行時資料夾)一起提供給使用者。

PyArmor Pro 專業版授權啟用

1. 更新 PyArmor 版本

確保您使用的是 PyArmor 9.0 或更新的版本。

pip install -U pyarmor
pyarmor -v

2. 首次啟用授權 (使用 `regcode` 檔案)

使用官方郵件附件中的 `regcode` 檔案進行首次啟用,成功後會生成 `regfile` 檔案。

pyarmor reg -p "YOUR_PRODUCT_NAME" pyarmor-regcode-XXXX.txt

3. 後續裝置註冊 (使用 `regfile` 檔案)

在其他裝置上註冊時,直接使用上一步生成的 `regfile` 檔案即可。

pyarmor reg pyarmor-regfile-XXXX.zip

重要注意事項

  • 請務必備份 `regcode` 和 `regfile` 檔案,官方不提供遺失找回服務。
  • `regcode` 僅用於首次啟用,後續註冊都應使用 `regfile`
  • 請勿在 Docker 或 CI/CD 流程中直接使用 `regfile` 註冊,這會快速消耗您的授權額度。

疑難排解:找不到平台擴充模組

問題描述

執行混淆或打包時,出現錯誤提示 PyArmor 無法找到特定平台的預建運行時擴充模組,例如 `linux.aarch64.3.8`。

根本原因

此錯誤表示 PyArmor 的預建庫中,沒有提供完全符合您目前作業系統與 Python 版本組合的動態庫檔案。

解決方案

這是最常見且有效的解決方法。舊的快取可能導致版本不匹配。

# 刪除現有的平台快取
rm -rf ~/.pyarmor/platforms

# 刪除後,重新執行您的混淆或打包指令
pyarmor gen your_script.py

平台名稱通常不需要包含 Python 的次要版本號。例如,Linux ARM64 平台應使用 `linux.aarch64`。

pyarmor gen --platform linux.aarch64 your_script.py

您可以手動檢查 PyArmor 實際支援的平台版本。

# 透過 help 指令查看
pyarmor --help

# 或直接查看已下載的平台資料夾
ls ~/.pyarmor/platforms/

如果指令參數無效,可以嘗試設定環境變數。

# Linux / macOS
export PYARMOR_PLATFORM=linux.aarch64
pyarmor gen your_script.py

# Windows
set PYARMOR_PLATFORM=linux.aarch64
pyarmor gen your_script.py

加密與自動化部署問題

此區塊統整了在使用 PyArmor 加密、透過批次檔 (.bat) 自動化打包,以及使用巨集 (.ttl) 部署到 Linux 伺服器時的常見問題與解決方案。

問題 1:ModuleNotFoundError: No module named 'pyarmor_runtime_...'

根本原因

PyArmor 加密後的 `.py` 檔案需要一個名為 `pyarmor_runtime_...` 的輔助資料夾才能執行。此錯誤表示您只上傳了加密的 `.py` 檔,而沒有一起上傳這個必要的 runtime 資料夾。

解決方案

在打包和部署時,必須將加密後 `dist` 目錄中的所有內容(包含主腳本檔案和 `pyarmor_runtime_...` 資料夾)完整地部署到目標環境。

問題 2:在 Windows 加密的檔案,無法在 Linux 伺服器上執行

根本原因

PyArmor 的 runtime 檔案是平台相關的。在 Windows 上產生的 runtime(例如包含 `.pyd` 檔)無法在 Linux 環境下運作(反之亦然),因為它們底層的二進位碼不同。

解決方案

  • 在目標平台加密(最可靠):在您的 Linux 伺服器上安裝 PyArmor,並直接在上面執行加密指令。
  • 跨平台加密:若需在 Windows 上產生適用於 Linux 的加密檔案,可在加密時使用 `--platform` 參數指定目標平台。
    # 在 Windows 上產生適用於 Linux x86_64 的加密檔案
    pyarmor gen --platform linux_x86_64 GLRT_PDF.py

問題 3:加密後目錄結構改變,導致 import 失敗

根本原因

PyArmor 加密時若指定輸出目錄(例如 `cpd_sdk/`),會改變原始檔案的相對位置,導致原本的 `import` 路徑失效。

解決方案

  • 修改 import 路徑:在您的主程式 `main.py` 中,明確指定從新的子目錄匯入。
    from cpd_sdk.GLRT_PDF import compute_glrt_metrics
  • 動態新增路徑 (不改 import):在 `main.py` 開頭將 SDK 資料夾的路徑動態加入到 Python 的搜尋路徑中,這樣就不需修改後續的 import 語句。
    import sys
    # 將 cpd_sdk 加到搜尋路徑的最前面
    sys.path.insert(0, "cpd_sdk")
    # 維持原樣
    from GLRT_PDF import compute_glrt_metrics