众所周知,Python是一种解释型语言。如果您不想向其他人显示您的代码,就可以通过编译或者加密等方式,下面提供3中加密方法:

  1. 通过 Pyinstaller 编译Python源码以生成 .exe 文件。
  2. 通过 Cython 编译Python源码以生成 .pyd 文件(Windows)或 .so 文件(Linux)。
  3. 通过 Pyarmor 生成加密后的Python源码。

其中,pyinstaller 会将代码和虚拟环境打包成一个 .exe 文件,而cython和pyarmor则只打包代码,需要配合Python解释器才能运行。

pyinstaller的教程见 Python打包成exe文件,本文主要介绍如何只加密代码,而不打包虚拟环境。

Cython编译Python源码

如果想加密python代码片段,可用Cython。

Windows python to .pyd

假设你有一个 test.py 文件

1
2
3
# test.py
def add(a, b):
return a+b

现在你想把 test.py 编译成一个 pyd 文件。创建一个 setup.py,如下:

1
2
3
4
5
# setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(name='test', ext_modules=cythonize('test.py'))
1
python setup.py build

这将创建一个 build 文件夹,其中包含生成的 .pyd 文件。将pyd文件复制到当前目录(个人习惯)并按如下方式调用 .pyd

1
2
3
4
5
from test import add

if __name__ == '__main__':
a, b = 1, 1
print(add(a, b))

或者使用 python setup.py build_ext --inplace 编译,这样就可以直接在当前目录中生成.pyd文件,然后按上述方式调用。

Linux python to .so

与windows生成 .pyd 文件类似,也以test.py为例,构建 setup.py 文件

1
2
3
4
5
# setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize(['test.py']))
1
python3 setup.py build_ext --inplace

调用 .so file

1
2
3
4
import ctypes

ll = ctypes.cdll.LoadLibrary
demo = ll("test.so")

Linux C++ to .so

1
gcc -shared -f PIC test.c -o test.so

Pyarmor编译Python源码

概述

  1. 加密机制: PyArmor 对代码的加密使用了高级的加密算法,并通过动态加载运行时库(如 pyarmor_runtime.so)来执行代码。这种加密方式并不只是简单的文件加密,而是通过将代码逻辑与运行时保护紧密结合,防止被破解。
  2. 需要密钥: PyArmor 加密的代码依赖于特定的加密密钥,这些密钥会存储在加密过程中生成的 .pyarmor_capsule.zip 文件或者通过许可证传递。如果没有正确的密钥,无法还原加密代码。
  3. 反向工程挑战: 即便拥有 pyarmor_runtime.so,反向工程和破解 PyArmor 加密代码需要深入的逆向工程技术,并且通常是非常困难且不被允许的,除非你是该代码的合法拥有者并有合法的访问权限。

如果想加密python文件,可用Pyarmor。源项目地址

使用Pyarmor

Pyarmor编译python源码,需要安装Pyarmor。

1
pip install pyarmor

然后加密 foo.py 脚本:

1
pyarmor gen foo.py

这时,会在当前目录下生成加密文件: dist/foo.pydist/pyarmor_runtime_000000 (该文件很重要,在运行加密文件使用),
dist/foo.py 内容类似如下:

1
2
from pyarmor_runtime import __pyarmor__
__pyarmor__(__name__, __file__, b'\x28\x83\x20\x58....')

将dist下生成的这两个文件替换加密前的文件,调用方式与原始文件一样。

Pyarmor其他功能

还有两个功能,pyarmor packpyarmor licenses 如下,笔者还未尝试,感兴趣的小伙伴可以尝试:
生成带加密的exe文件:

1
pyarmor pack --output=packed_script.exe foo.py

还可以设置加密的过期时间,先设置licenses.lic文件,再加密:

1
pyarmor licenses --expire=2026-01-01 foo@example.com

这个命令会为 foo@example.com 用户生成一个有效期到 2026 年 1 月 1 日的许可证文件。生成的许可证文件默认会命名为 foo@example.com.lic,并保存在当前目录中。

设置好过期时间,再对软件进行加密,加密过程中会自动使用生成的许可证文件:

1
pyarmor gen foo.py