PyArmor 实战指南:加密 Python 项目并跨机器运行的全流程解析
在 Python 应用加密与发布场景中,PyArmor 是一个非常实用的工具。它可以把 Python 脚本转换成难以反向工程的形式,同时提供运行时判断、授权许可等机制,非常适合用于保护商业逻辑。
本文将结合实践经验和官方行为说明,步骤化地讲解如何:
📌 在源机器加密 Python 项目
📌 确保加密后可以复制到其他机器并运行
📌 避免常见错误与坑
📌 配置与运行依赖环境
一、注意 Python 版本
当你在一台机器上加密了你的项目,然后把加密后的 dist 文件夹复制到另一台机器运行时,很容易遇到类似这样的错误:
首先需要在全局使用python 3.10.11版本,在源机器加密之后,如果想要copy 加密后的项目到另一个机器上运行,必须要保证另一台机器运行时使用的也是相同的python版本,否则会报错:
(.venv) PS C:\Users\Admin003\Desktop\dist> C:\Users\Admin003\AppData\Local\Programs\Python\Python310\python app_realtime.py
Traceback (most recent call last):
File "C:\Users\Admin003\Desktop\dist\app_realtime.py", line 2, in <module>
from pyarmor_runtime_000000 import __pyarmor__
File "C:\Users\Admin003\Desktop\dist\pyarmor_runtime_000000\__init__.py", line 2, in <module>
from .pyarmor_runtime import __pyarmor__
ImportError: DLL load failed while importing pyarmor_runtime: The specified module could not be found.这是因为 PyArmor 的运行时模块(pyarmor_runtime.pyd 等二进制扩展)依赖于特定版本的 Python 解释器和平台架构。它并不是一个纯 Python 文件,而是与 Python 内部 ABI 紧密绑定的二进制扩展。因此:
✔ 加密运行时一定要用 Python 3.10.11
✔ 目标机器也必须用 Python 3.10.11(且位数相同,如 x64)运行
✘ 否则就会出现 DLL 加载失败或 Marshal 序列化错误等异常
这是 PyArmor 官方文档明确指出的行为,因为运行时扩展包含平台和 Python 版本特定的信息,而不能跨版本运行。
换句话说:目标机器运行环境要与源机器尽可能一致,特别是Python版本,否则即使代码存在,动态库运行也会失败。
二、安装 PyArmor 与注意事项
在源机器上安装 PyArmor:
pip install pyarmor 这里安装的是 PyArmor 的免费版本。它对于小项目足够使用,但在加密大文件夹时可能会遇到如:out of license这类错误。这是因为试用版对一些复杂/大的目录结构有功能限制。
三、生成加密结果(指定 Python 版本)
在项目根目录执行:
& "C:\Users\Hasee\AppData\Roaming\Python\Python310\Scripts\pyarmor.exe" generate --output dist .这是推荐的命令形式,它指定了使用特定 Python 环境下的 pyarmor 工具,并且给出了输出目录。
执行结果会在当前目录下生成一个完整的 dist 目录,其中包含:
📌 加密后的脚本(*.py)
📌 支持运行的辅助文件与运行时扩展(runtime package)
📌 许可文件(license.lic)
📌 授权密钥文件(pytransform.key)
四、复制pytransform.py文件到 dist
pytransform.py 是 PyArmor 运行时的核心文件之一,必须放入 dist 目录。
Copy-Item -Force "C:\Users\Hasee\AppData\Roaming\Python\Python310\site-packages\pyarmor\pytransform.py" -Destination ".\dist\pytransform.py"为什么需要它,设计到PyArmor 使用分层的运行时架构:
pyarmor_runtime.pyd :底层 DLL 负责核心解密逻辑
pytransform.py :上层 Python 接口,提供易用的 API
pyarmor_runtime_000000/__init__.py :初始化入口
这三个文件配合工作,才能确保加密后的代码在目标机器上正常运行。
如果不放入:
加密后的程序会抛出 ModuleNotFoundError: No module named 'pytransform' 或类似错误
无法正确加载和执行加密的 Python 模块
程序无法正常运行
五、dist 目录结构
最终的目录可能看起来像这样:
dist/
├── app_realtime.py
├── other_encrypted_scripts.py
├── pytransform.py
├── pytransform.key ← 可选:项目密钥文件
├── license.lic ← 可选:运行时许可证文件
└── pyarmor_runtime_000000/
├── __init__.py
└── pyarmor_runtime.pyd ← 加密运行时动态库5.1 pytransform.key:什么是它?什么时候需要?
5.1.1 作用
pytransform.key 是 项目级别的密钥文件,用于让运行时动态库和加密脚本一致:它包含了用于对字节码加密/解密的信息。
这是 PyArmor 生成的本地(项目)密钥,而不是全局的默认密钥。
5.1.2 全局密钥 vs 项目密钥
PyArmor 有两种密钥来源:
全局密钥箱(~/.pyarmor/.pyarmor_capsule.zip):这是默认的“密钥仓库”,如果你没有显式生成项目密钥,那么 PyArmor 使用的就是它里面的密钥进行加密。
项目密钥文件(pytransform.key):当你明确为某个项目生成专用密钥时,会得到这个文件。生成这个文件后,把它加到 dist 里可以让此 dist 包拥有自己的“独立密钥”,不再依赖全局密钥箱。
5.1.3 为什么没放它也能运行?
这是因为:如果没有本地的 pytransform.key,PyArmor 运行时 会回退去使用全局密钥箱中的密钥 来解密和执行代码。
运行时的查找顺序是:
当前目录下的
license.lic和pytransform.keypytransform.py所在目录里的这两个文件动态库内内嵌的默认许可/密钥
因此只要能找到可用的密钥和动态库,脚本是可以正常执行的。
5.1.4 什么时候才需要 pytransform.key?
建议显式生成和使用 pytransform.key 的场景:
为同一项目重复加密多个版本,确保版本之间密钥一致
多个客户需要不同授权许可 时,需要基于相同 project key 生成不同 license 文件
想离线管理每个项目的密钥,便于长期维护和控制
5.1.5 如何显式生成项目密钥文件?
用下面命令生成项目专用密钥:
pyarmor gen key --output keys
该命令会在当前目录的 keys/ 下生成一个 pytransform.key。
之后你可以复制到 dist:
Copy-Item keys\pytransform.key dist\
这样 dist 就带上了你自己项目的密钥,而不是依赖全局密钥箱。
5.2 license.lic:什么是它?什么时候需要它?
5.2.1 默认 license.lic 的作用
当你用 PyArmor 标准命令加密时,加密引擎会生成一个默认的 license.lic 放在 dist(以前版本是单独文件,现在一些版本甚至把它嵌入到了动态库里)。
这个默认 license.lic:
✔ 表示“允许加密脚本在任何机器上全部运行”
✔ 没有过期时间、没有设备绑定
✔ 是最宽松的许可
根据官方文档,在新版 PyArmor 中默认许可信息已经可以被嵌入动态库,因此 即使没有单独 license.lic 文件,脚本仍能运行。
5.2.2 自定义 license.lic 的意义
如果你希望对发布版做授权控制,则需要生成自定义的 license.lic:
🔸 设置使用期限(过期时间)
🔸 绑定特定机器(MAC、硬盘序列号)运行
🔸 限制只能在指定环境运行
这时就不能使用默认的“无限制许可证”,必须给客户一个单独的 license.lic。
5.1.3 如何生成自定义许可证?
PyArmor 提供命令来生成不同策略的许可证文件:
✨ 生成带过期时间的许可证
pyarmor licenses --expired 2025-12-31 myproj
执行后,会在类似:
licenses/myproj/license.lic
路径下生成一个新的许可证文件,可以拷贝到 dist:
Copy-Item licenses\myproj\license.lic dist\
✨ 生成绑定机器的许可证
pyarmor licenses --bind-disk "硬盘序列号" --bind-mac "MAC地址" myprojb
这个许可证只允许在该硬盘和该 MAC 的机器上运行。
官方文档说明:
加密后的脚本在运行时会先尝试在当前路径查找
license.lic和pytransform.key,
如果找不到,再去pytransform.py所在目录查找。
最后,如果没有这些文件也没有错误,那么运行时可能使用动态库内嵌的默认许可。
六、放入.env配置文件
将环境配置放入到dist目录,但是不能放入任何敏感信息,因为一旦运行时,所有的变量都是可获取的明文
七、安装项目依赖并运行
加密后的项目通常仍然需要依赖其他库(比如 Flask、aiohttp、mmpose 等),因此你需要在目标机器上:
创建虚拟环境:
python -m venv .venv激活虚拟环境:
C:\Code\Navtalk\Services\MuseTalk\.venv\Scripts\Activate.ps1安装依赖等等。
运行目标 Python 脚本:
python app_realtime.py这时:
✔ Python 会先加载 PyArmor 运行时扩展
✔ 再执行加密后的脚本逻辑
✔ 你得到与未加密版本相同的运行效果
- 感谢你赐予我前进的力量

