使用pyarmor对python项目进行licence加密

前言:对python项目进行加密设置,实现 日期 + ip 的 licence 加密

一、pyarmor 介绍

PyArmor 是一款商业 Python 代码加密工具,可通过字节码转换、机器码编译等技术保护 Python 代码不被逆向工程。它主要用于保护商业软件、算法知识产权或敏感代码逻辑,防止未授权访问、修改或复制。
核心功能

  • 代码加密
    转换 Python 字节码为混淆格式,生成加密脚本。
    支持直接运行加密代码,无需额外解密步骤。
  • 多平台支持
    兼容 Windows、Linux、macOS 等主流操作系统。
    支持 x86、ARM 等多种硬件架构。
  • 运行时保护
    检测调试器、反编译工具,防止动态分析。
    限制程序在特定机器、时间或环境中运行。
  • 灵活部署
    可选择性加密部分模块,保留纯 Python 代码兼容性。
    支持加密 Python 包(Package)和应用程序。

二、单脚步加密

2.1 日期加密

2.1.1 单次设置加密方式

(1)安装包

bash 复制代码
pip install pyarmor

(2)创建测试脚本

hello.py脚本

python 复制代码
for i in range(10):
    print(i, 'run success')

(3)执行日期加密命令

bash 复制代码
pyarmor gen -e "2025-07-02T17:20:00" hello.py
  • -e : 有效期日期,我这里设置的是运行时的20分钟之内(也可以直接填入整数,单位为天)
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>pyarmor gen -e "2025-07-02T17:20:00" hello.py    
INFO     Python 3.10.0
INFO     Pyarmor 9.1.7 (trial), 000000, non-profits
INFO     Platform windows.x86_64
INFO     search inputs ...
INFO     find script hello.py
INFO     find 1 top resources
INFO     start to generate runtime files
INFO     target platforms {'windows.amd64'}
INFO     write dist\pyarmor_runtime_000000\pyarmor_runtime.pyd
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

(4)运行加密后的文件

bash 复制代码
python dist/hello.py
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>python dist/hello.py
0 run success
1 run success
2 run success
3 run success
4 run success
5 run success
6 run success
7 run success
8 run success
9 run success

(5)日期时间过了之后运行结果

bash 复制代码
python dist/hello.py
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>python dist/hello.py
Traceback (most recent call last):
  File "E:\zhx\workspace_2025\DaBao\module_Read\dist\hello.py", line 2, in <module>
    from pyarmor_runtime_000000 import __pyarmor__
  File "E:\zhx\workspace_2025\DaBao\module_Read\dist\pyarmor_runtime_000000\__init__.py", line 2, in <module>
    from .pyarmor_runtime import __pyarmor__
RuntimeError: this license key is expired (1:11086)

提醒 licence 过期了

2.1.2 使用外部文件存放运行密钥

(1)在加密脚本的时候指定使用外部密钥

bash 复制代码
pyarmor gen --outer hello.py 
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>pyarmor gen --outer hello.py 
INFO     Python 3.10.0
INFO     Pyarmor 9.1.7 (trial), 000000, non-profits
INFO     Platform windows.x86_64
INFO     search inputs ...
INFO     find script hello.py
INFO     find 1 top resources
INFO     start to generate runtime files
INFO     target platforms {'windows.amd64'}
INFO     write dist\pyarmor_runtime_000000\pyarmor_runtime.pyd
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

(2)运行加密的文件

bash 复制代码
python dist/hello.py
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>python dist/hello.py
Traceback (most recent call last):
  File "E:\zhx\workspace_2025\DaBao\module_Read\dist\hello.py", line 2, in <module>
    from pyarmor_runtime_000000 import __pyarmor__
  File "E:\zhx\workspace_2025\DaBao\module_Read\dist\pyarmor_runtime_000000\__init__.py", line 2, in <module>
    from .pyarmor_runtime import __pyarmor__
RuntimeError: missing license key to run the script (1:10672)

提醒 licence 不存在

(3)生成 licence

bash 复制代码
pyarmor gen key -O dist/key111 -e 1 
  • -e 设置为 1 天
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>pyarmor gen key -O dist/key111 -e 1 
INFO     Python 3.10.0
INFO     Pyarmor 9.1.7 (trial), 000000, non-profits
INFO     Platform windows.x86_64
INFO     start to generate outer runtime key "pyarmor.rkey"
INFO     write dist/key111\pyarmor.rkey
INFO     generate outer runtime key OK

将 dist/key111//pyarmor.rkey 下的licence 拷贝到 hello的加密文件dist/pyarmor_runtime_000000/ 下

bash 复制代码
cp dist/key2/pyarmor.rkey dist/pyarmor_runtime_000000/

(4)运行查看

bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao\module_Read>python dist/hello.py
0 run success
1 run success
2 run success
3 run success
4 run success
5 run success
6 run success
7 run success
8 run success
9 run success

正常可以运行了

2.2 周期性检查运行密钥

当运行加密的服务时一直处于运行的状态时,需要设置周期性检查命令。

使用下面的命令生成的加密脚本,运行的时候会每隔一个小时对运行密钥进行一次检查

bash 复制代码
pyarmor gen --period 1 hello.py

2.3 日期+设备ip 加密

使用下面的命令绑定加密脚本到多台设备:

bash 复制代码
pyarmor gen -e 1 -b "fe80::6172:250a:329d:3f97" -b "f48:tf:f2:j7:70:2f" hello.py
  • -b :物理地址 / ip / ipv4地址
  • -e :日期

注意: 当我使用linux上的mac地址时是没有问题的,但是当我使用windows的物理地址是会报 "ERROR invalid device info "9C-***-44" " ,这个时候我们只需要把windows物理地址中的 '-' 改成 ':' 就行了。

测试:当在其他设备上运行时

bash 复制代码
Traceback (most recent call last):
  File "/home/ws/store/zhx/workspace_2024/dist/dd.py", line 2, in <module>
    from pyarmor_runtime_000000 import __pyarmor__
  File "/home/ws/store/zhx/workspace_2024/dist/pyarmor_runtime_000000/__init__.py", line 2, in <module>
    from .pyarmor_runtime import __pyarmor__
RuntimeError: 脚本许可证不可用于当前设备 (1:10252)

三、python项目加密

3.1 使用单次加密方式

3.1.1 查看待打包的python项目目录


3.1.2 命令介绍

  • -r :递归搜索目录下面的 Python 脚本,否则只搜索当前目录下面的脚本
  • -i :保存运行辅助文件到加密包的内部。
  • -O :设置加密脚本的输出路径,默认值是 dist

3.1.3 分析

(1)在脚本互相引用的时候,需要把路径写全,如下在serverMain.py中引用:

python 复制代码
from module_Read.Router_Read import RouterRead

(2) 如果使用直接对整个项目进行加密时

bash 复制代码
pyarmor gen -e 1 -r -i DaBao

运行加密后的文件会报错1

bash 复制代码
(smart_campus) E:\zhx\workspace_2025>python dist/DaBao/serverMain.py
Traceback (most recent call last):
  File "E:\zhx\workspace_2025\dist\DaBao\serverMain.py", line 2, in <module>
    from .pyarmor_runtime_000000 import __pyarmor__
ImportError: attempted relative import with no known parent package

报错2

bash 复制代码
(smart_campus) E:\zhx\workspace_2025>python -m dist.DaBao.serverMain
Traceback (most recent call last):
  File "F:\anaconda3\envs\smart_campus\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "F:\anaconda3\envs\smart_campus\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "<frozen __main__>", line 3, in <module>
  File "<frozen DaBao.serverMain>", line 11, in <module>
ModuleNotFoundError: No module named 'module_Read'

3.1.4 正确的加密方式

因为我们的所有代码是在DaBao下,对应的在dist/下包含DaBao下所有的代码,为了名称统一,使用 -O 输出路径把dist改成DaBao。

然后对应DaBao中的代码,有configs、module_Logging、module_Read、tet4个文件夹,一个serverMain.py 脚本,所有我们需要区分开加密,文件夹的需要使用 "-r -i" 这 两个参数,对应 "serverMain.py" 则不需要。
注: 每个文件夹(不管几层,每层都需要)下都必须包含"init.py" 脚本 ,确保每个文件夹都被加载

(1)文件夹加密(需要保存为DaBao的话使用-O参数,这里使用默认的dist)

bash 复制代码
pyarmor gen -e 1 -r -i module_Read configs module_Logging tet
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao>pyarmor gen -e 1 -r -i module_Read configs module_Logging tet
INFO     Python 3.10.0
INFO     Pyarmor 9.1.7 (trial), 000000, non-profits
INFO     Platform windows.x86_64
INFO     search inputs ...
INFO     find package at module_Read
INFO     find package at configs
INFO     find package at module_Logging
INFO     find package at tet
INFO     find 4 top resources
INFO     start to generate runtime files
INFO     target platforms {'windows.amd64'}
INFO     write dist\module_Read\pyarmor_runtime_000000\pyarmor_runtime.pyd
INFO     generate runtime files OK
INFO     start to obfuscate scripts
INFO     process resource "module_Read"
INFO     obfuscating file readExcel.py
INFO     write dist\module_Read\readExcel.py
INFO     obfuscating file read_document.py
INFO     write dist\module_Read\read_document.py
INFO     obfuscating file read_excel.py
INFO     write dist\module_Read\read_excel.py
INFO     obfuscating file Router_Read.py
INFO     write dist\module_Read\Router_Read.py
INFO     obfuscating file toolRead.py
INFO     write dist\module_Read\toolRead.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\__init__.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\data\__init__.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\static\__init__.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\static\111\__init__.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\static\documents\__init__.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Read\static\file_img\__init__.py
INFO     process resource "configs"
INFO     obfuscating file config.py
INFO     write dist\configs\config.py
INFO     obfuscating file __init__.py
INFO     write dist\configs\__init__.py
INFO     process resource "module_Logging"
INFO     obfuscating file loggingD1.py
INFO     write dist\module_Logging\loggingD1.py
INFO     obfuscating file __init__.py
INFO     write dist\module_Logging\__init__.py
INFO     process resource "tet"
INFO     obfuscating file dd.py
INFO     write dist\tet\dd.py
INFO     obfuscating file hello.py
INFO     write dist\tet\hello.py
INFO     obfuscating file hh.py
INFO     write dist\tet\hh.py
INFO     obfuscating file __init__.py
INFO     write dist\tet\__init__.py
INFO     obfuscate scripts OK

(2)脚本加密

bash 复制代码
pyarmor gen -e 1 serverMain.py
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao>pyarmor gen -e 1 serverMain.py                               
INFO     Python 3.10.0
INFO     Pyarmor 9.1.7 (trial), 000000, non-profits
INFO     Platform windows.x86_64
INFO     search inputs ...
INFO     find script serverMain.py
INFO     find 1 top resources
INFO     start to generate runtime files
INFO     target platforms {'windows.amd64'}
INFO     write dist\pyarmor_runtime_000000\pyarmor_runtime.pyd
INFO     generate runtime files OK
INFO     start to obfuscate scripts
INFO     process resource "serverMain"
INFO     obfuscating file serverMain.py
INFO     write dist\serverMain.py
INFO     obfuscate scripts OK

3.1.5 运行加密文件

bash 复制代码
python dist/serverMain.py
bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao>python dist/serverMain.py
INFO:     Uvicorn running on http://0.0.0.0:8208 (Press CTRL+C to quit)
INFO:     Started parent process [36260]
INFO:     Started server process [36624]
INFO:     Waiting for application startup.
INFO:     Started server process [34520]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Application startup complete.

调用接口测试

3.2 使用外部文件存放运行密钥

3.2.1 外部加密

bash 复制代码
pyarmor gen --outer -r -i configs module_Logging module_Read tet serverMain.py
pyarmor gen --outer serverMain.py

运行测试报不存在licence

bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao>python dist/serverMain.py
Traceback (most recent call last):
  File "E:\zhx\workspace_2025\DaBao\dist\serverMain.py", line 2, in <module>
    from pyarmor_runtime_000000 import __pyarmor__
  File "E:\zhx\workspace_2025\DaBao\dist\pyarmor_runtime_000000\__init__.py", line 2, in <module>
    from .pyarmor_runtime import __pyarmor__
RuntimeError: missing license key to run the script (1:10672)

3.2.2 生成licence

时效为5分钟之内

bash 复制代码
pyarmor gen key -O key222 -e "2025-07-03T11:55:00"

将这个licence粘贴到每个 pyarmor_runtime_000000 下

运行看结果

等5分钟后运行看结果

已经提醒licence过期了

3.2.3 周期性检查

由于当前代码运行之后是一个服务,只要启动的时候licence没有过期则可以一直运行着,可以使用 --period 参数对正在运行的服务进行周期性的检查

bash 复制代码
pyarmor gen key --period 1 -O key222 -e "2025-07-03T12:30:00"

然后把服务起来,1小时之后会进行自动检查

bash 复制代码
(smart_campus) E:\zhx\workspace_2025\DaBao>python dist/serverMain.py
INFO:     Uvicorn running on http://0.0.0.0:8208 (Press CTRL+C to quit)
INFO:     Started parent process [34736]
INFO:     Started server process [8884]
INFO:     Started server process [15508]
INFO:     Waiting for application startup.
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Application startup complete.

一个小时后重新调用

bash 复制代码
INFO:     192.168.1.155:52219 - "POST /Reader/DocumentReader HTTP/1.1" 200 OK
INFO:     192.168.1.155:63661 - "POST /Reader/DocumentReader HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 403, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\fastapi\applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
    raise exc
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\starlette\routing.py", line 73, in app
    response = await f(request)
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\fastapi\routing.py", line 301, in app
    raw_response = await run_endpoint_function(
  File "F:\anaconda3\envs\smart_campus\lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
  File "<frozen module_Read.Router_Read>", line 23, in DocumentReader
RuntimeError: this license key is expired (1:11086)

看到提醒licence过期了。

四、绑定平台

  • --platform

用于跨平台加密脚本指定运行加密脚本的目标平台

这个选项可以使用多次,也可以使用逗号把多个平台名称分开

平台名称必须是 Pyarmor 定义的 运行平台 名称

  • Windows
    • windows.x86_64
    • windows.x86
  • Many Linuxs
    • linux.x86_64
    • linux.x86
    • linux.aarch64
    • linux.armv7
  • Apple Intel and Silicon
    • darwin.x86_64
    • darwin.aarch64 or darwin.arm64
  • FreeBSD
    • freebsd.x86_64
  • Alpine Linux (musl-c)
    • alpine.x86_64
    • alpine.aarch64
  • Android
    • android.x86_64
    • android.x86
    • android.aarch64
    • android.armv7
相关推荐
念念01072 小时前
数学建模竞赛中评价类相关模型
python·数学建模·因子分析·topsis
四维碎片2 小时前
【Qt】线程池与全局信号实现异步协作
开发语言·qt·ui·visual studio
IT码农-爱吃辣条2 小时前
Three.js 初级教程大全
开发语言·javascript·three.js
云天徽上3 小时前
【数据可视化-94】2025 亚洲杯总决赛数据可视化分析:澳大利亚队 vs 中国队
python·信息可视化·数据挖掘·数据分析·数据可视化·pyecharts
☺����3 小时前
实现自己的AI视频监控系统-第一章-视频拉流与解码2
开发语言·人工智能·python·音视频
染翰3 小时前
lua入门以及在Redis中的应用
开发语言·redis·lua
王者鳜錸3 小时前
PYTHON让繁琐的工作自动化-函数
开发语言·python·自动化
兔老大RabbitMQ4 小时前
git pull origin master失败
java·开发语言·git
tt5555555555554 小时前
C/C++嵌入式笔试核心考点精解
c语言·开发语言·c++
xiao助阵4 小时前
python实现梅尔频率倒谱系数(MFCC) 除了傅里叶变换和离散余弦变换
开发语言·python