在当今的软件开发领域,源代码的安全保护变得越来越重要。Python作为一种解释型语言,其代码通常以明文形式存在,这使得源代码容易被他人获取和复制。为了应对这一挑战,PyArmor 应运而生,它是一款专门用于保护Python代码的工具,能够有效防止源代码泄露和盗用。
简介
PyArmor 是一个命令行工具,用于混淆Python脚本,将混淆后的脚本绑定到特定机器上,或在特定时间使混淆后的脚本过期。它能够在Python代码运行时保护其二进制代码不被泄露,设置加密后Python源代码的有效期限,并将加密后的Python源代码绑定到硬盘、网卡等硬件设备上。
Python作为一种开源的编程语言,其源代码易于获取和阅读,这对于一些商业软件或关键代码的保护带来了挑战。PyArmor 的出现就是为了应对这一问题,它提供了一种可靠的方式来保护Python代码,防止源代码泄露和盗用,从而保护软件的知识产权和商业利益。
pip install pyarmor
代码示例
这次写一个极简的 hello.py 文件:
print('Hello world!')
对这个 hello.py 执行加密:
$ pyarmor gen hello.py
INFO Python 3.12.9
INFO Pyarmor 9.1.4 (trial), 000000, non-profits
INFO Platform linux.x86_64
INFO search inputs ...
INFO find script hello.py
INFO find 1 top resources
INFO start to generate runtime files
INFO target platforms {'linux.x86_64'}
INFO write dist/pyarmor_runtime_000000/pyarmor_runtime.so
INFO generate runtime files OK
INFO start to obfuscate scripts
INFO process resource "hello"
INFO obfuscating file hello.py
INFO write dist/hello.py
INFO obfuscate scripts OK
$ tree # 执行前只有一个 hello.py 文件,执行后则增加了 dist 目录
.
├── dist
│ ├── hello.py
│ └── pyarmor_runtime_000000
│ ├── __init__.py
│ └── pyarmor_runtime.so
└── hello.py
2 directories, 4 files
$ python dist/hello.py
Hello world!
这个 dist 目录下的内容,就是混淆后的交付件。功能上,和原先明文的 Python 脚本、模块,完全一致。但是不会被逆向工程,看破源码。
结合PyInstaller
先执行加密,再进行打包,即可完成结合。
$ pyinstaller -F dist/hello.py # 不要错选为项目根目录的 hello.py,否则会得到未加密的结果
108 INFO: PyInstaller: 6.13.0, contrib hooks: 2025.3
108 INFO: Python: 3.12.9
... (省略后面的日志,大约需要等1分钟)
$ tree # 多出了很多 PyInstaller 相关的过程文件
.
├── build
│ └── hello
│ ├── Analysis-00.toc
│ ├── base_library.zip
│ ├── EXE-00.toc
│ ├── hello.pkg
│ ├── localpycs
│ │ ├── pyimod01_archive.pyc
│ │ ├── pyimod02_importers.pyc
│ │ ├── pyimod03_ctypes.pyc
│ │ └── struct.pyc
│ ├── PKG-00.toc
│ ├── PYZ-00.pyz
│ ├── PYZ-00.toc
│ ├── warn-hello.txt
│ └── xref-hello.html
├── dist
│ ├── hello
│ ├── hello.py
│ └── pyarmor_runtime_000000
│ ├── __init__.py
│ └── pyarmor_runtime.so
├── hello.py
└── hello.spec
5 directories, 19 files
$ ./dist/hello
Hello world!
dist/hello.py 是混淆后的文件(入口),dist/hello 则是打包后的可执行文件。
技术实现
PyArmor 加密后的脚本仍然是一个有效的Python脚本,只是内容已经加密。通过额外的扩展模块pytransform,纯文本Python脚本可以无缝地被加密脚本替换。PyArmor 与其它二进制打包工具,兼容性很好,可以配合使用,如 PyInstaller 等。
PyArmor 的运行时混淆功能非常强大,它会在每个代码对象完成执行后,立即将其字节码混淆,同时清除帧的局部变量。这种机制确保了即使有人试图通过调试或内存分析来获取代码,也会面临极大的困难。
它提供了两种主要的不可逆混淆模式:
- RFT模式(Rename Functions and Types):重命名源代码中的函数、方法、类、变量和参数。这种重命名使得代码难以被理解和分析,增加了逆向工程的难度。
- BCC模式(Bind C Code):将一些Python函数转换为C函数,并使用高优化选项编译成机器指令,从而实现不可逆的混淆。这种方式使得代码难以被逆向工程,因为它已经不是纯粹的Python代码了。
PyArmor 可以将加密后的脚本绑定到特定的硬件设备上,例如硬盘或网卡,这样脚本只能在特定的机器上运行。此外,它还可以设置加密后脚本的使用期限,超过期限后脚本将无法运行。所以,也能当做正版授权的一种技术手段来使用。
在以上示例中,虽然源文件 hello.py 是一个简单的 helloworld 示例,但其加密、混淆后的内容,已经爹妈都不认识了。
$ cat dist/hello.py
# Pyarmor 9.1.4 (trial), 000000, non-profits, 2025-04-20T10:48:07.429060
from pyarmor_runtime_000000 import __pyarmor__
__pyarmor__(__name__, __file__, b'PY000000\x00\x03\x0c\x00\xcb\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xb4\x01\x00\x00\x12\t\x04\x00^#\xf6\xebMR\xc9\xc2$\xc9\xd8Q\x0c\x94\xc4\x17\x00\x00\x00\x00\x00\x00\x00\x00\x02\xc6\xf7#\xfb\x10\x1d#R\x8e\xf4\x85\xa2\x08\xa1\xef|Uk\x0bhT\xde3*\x98\xaa\x04\r\xf68\xe9\x03\xdd\r/\x88\xe2\xd2\x1a\xbd\x14=\x0c\xec\x9a\x08,\x0e\xb3q\xc2\x80\x81\xd0\x97\xc6\x1eJ\xab>\x8cZC\xd7\x9d\xf0\xa4\x0ct\xb0\xf5\xfa8`O;\x10uH\xf9\xd9\x85\xd3\x97\x81&\xcem\xe3\xba/\xece\xdf:\xef[\xf4\xb4\xa8\x9e\xda\xd4\x19&~\t\xd0\xc4\x9f?\xa1e\xf4A\xa4\x89\xfdEuu\x8b\x1c\x15\xb8V\xe1\'09\xe0\xe6V\xb0\xef\xc7~\xcd\xcckn\x13 q\xcf\xe3\x12<\xf7\xf9\xa9j$[=H\xb19\xcd@\xf1"X\n\x10\x8d\xf8\'\x82\x7f1@AI\xe7\x91\xd4\xcf\x86<\t\xed\xe6\xae\x84\xe0\xda\xa8\xa5\xac\r\x8620$\xdc\xf0J\xf6\tZ]\xb3\x16\x13\xa6\xa5\x18\xcc\x9e\x96@\xba\xe8\x1f\xe2\xe1&\x93\xca\xc4\xee\xdb\xf3\xae\xa3\xb4g3\xf4\xb4\x87\xd9\xb6G\xa9L\xe0\xcdL\xccY\x98\x85\xe6\x1e\xef>\xdeO\xb5\x18\x96\xec\x96\x95/\xcc\xa7\xb4s;ed\x8be\x0c\x9f\xf1\x1bCh~d\x17\x0e\x03\xbb\xf3S\x11L*\x83\xd8\xa2Cn\x95\xd1\x8b~R\xf2\xf9\xf9V\x04\x86FSn\x08AL\x1e\xf5\x15\xb9V\x00\xcd@E.\x11]\x87\x0f\xf5/\xeb\xee\x9d\xc1\xa2NLh\x99$\xc6"z\x9b\x08G\x88\x8dV\x11\x1cL\tV\x95\xa5\x97B:~)6B\x08J\xa6)\xaeCC\xad\xeai\xa5\xfdD_\xd8\xad`~,.\x05\xf8S\xd3\xd85KV\xad\x07\x8ap\x1b\xafe\xcb\xa4\xea\x02\x94gZ\xaf\x94\xd7h#KN\x8e\xb5\xc0\x90\xcf\x12*\xc7i}D4\x8f\xcez\xbe\xcc\xce\x1d\t\x18&\xaf\xe1\xe1.^\xb6\rg\xc7V')
限制条件
PyArmor 主要是为 CPython 开发的,在其它的 Runtime 下会有一些问题,比如:
- PyPy
- Boost::python
- WASM
另外,要注意 PyArmor 并非开源软件,而是试用版免费。非商业项目、未盈利商业项目,不用付费,而有盈利的商业项目,需要升级 License,并且付费。除了最后的“管线版”,其它付费模式都是一次性付费。
| 基础版 | 专家版 | 集团版 | 管线版 | |
加密大脚本和混淆字符串 | Y | Y | Y | Y | |
不可逆加密模式 BCC / RFT | Y | Y | Y | ||
构建设备离线加密 | Y | Y | |||
最多构建设备数目 * | 100 | 100 | 200 | 0 | |
在本地设备运行不受限制的 Docker ** | Y | ||||
在 CI/CD 集成环境使用 | Y | Y | Y |
如果需要了解购买详情,可以查看官网的:Pyarmor 电子订单
由于加密和混淆的开销,使用PyArmor保护后的Python脚本可能会有一定的性能损失。当项目包含复杂的依赖关系时,使用PyArmor和PyInstaller进行打包可能会遇到一些问题,需要开发者仔细配置。
最后,尽管PyArmor提供了强大的保护机制,但理论上仍然存在被破解的可能性。不过,根据目前的信息,PyArmor v8版本的加密机制尚未被破解,安全性相对较高。
总结
PyArmor 是一款功能强大的Python代码保护工具,它通过多种技术手段保护Python代码不被泄露和盗用。
随着Python在商业软件和关键代码保护领域的应用越来越广泛,代码安全保护的需求也日益增长。PyArmor 作为一种有效的代码保护工具,将在这一趋势中发挥越来越重要的作用。
它闭源商用的特点,对普通开发者来说,基本不用在意。而对于真正有需要保护商业利益,在交付可执行程序后,需要保护自研代码知识产权的开发团队来说,额外的安全服务支出,不多,而且必要。