python算法加密 pyarmor与docker
作者:hellobigorange 发布时间:2023-02-15 02:17:32
前言
为了避免代码泄露的风险,我们往往需要对代码进行加密,PyArmor
是一个用于加密和保护 Python
脚本的工具。它能够在运行时刻保护 Python
脚本的二进制代码不被泄露,设置加密后Python
源代码的有效期限,绑 定加密后的Python
源代码到硬盘、网卡等硬件设备。
一 基础配置 安装
pip install pyarmor
更新到最新版本:
pip install --upgrade pyarmor
二 基本语法 2.1 加密 Python 脚本
a) 单个包,只有单级目录
使用命令obfuscate
来加密 python 脚本。在最简单的情况下,最常用的一种情况是切换到主函数脚本algorithm.py
所在的路径,然后执行:
pyarmor obfuscate algorithm.py
PyArmor 会加密 algorithm.py
和相同目录下面的所有 *.py 文件
:
创建输出子目录
dist
生成加密的主脚本
algorithm.py
保存在输出目录dist
加密相同目录下其他所有
*.py
文件,保存到输出目录dist
生成运行加密脚本所需要的全部辅助文件,保存到输出目录
dist
b) 若有多个算法包、多级目录
默认情况下,只有和主脚本相同目录的其他 *.py
会被同时加密。如果想递归加密 子目录下的所有 *.py
文件,使用下面的命令:
pyarmor obfuscate --recursive algorithm.py
注意:只能加密.py
文件,如果算法需要调用.csv
,.json
文件,直接拷贝到dist
文件夹对应的包里就可以了
2.2 运行加密脚本
运行加密脚本不需要安装pyarmo
cd dist
python algorithm.py
2.3 发布加密脚本
执行到这一步已经可以发布加密脚本了,发布加密脚本只需要把输出路径的所有dist
文件拷贝即可。
三、pyarmor&docker
由于pyarmo
加密的脚本对运行环境比较敏感,因此我们最好把整个算法打包成镜像,在启动容器的时候进行加密,并删除所有的未加密文件,留下dist
文件
注:上文也说过,pyarmo只能对
.py
文件加密,对于.csv
,.json
文件是无法加密的,自然在生成的dist
包里也没有非.py
后缀的文件,因此我们需要将.csv
等文件移入到dist
里,不然运行dist
里的算法时会报错。
由于我本地是windows
系统,所以生成.dll
后缀文件,直接把dist制作成镜像会报错,因为容器运行需要.so
文件,因此考虑在容器中运行时加密,生成.so
,再自动移除未加密文键,只留下dist
及所需的非.py
后缀文件,其实也可以用linux
系统直接本地运行生成dist
,但是不要忘记将非.py
后缀的文件及文件夹复制进去。
下面将以myprocessor
的算法包为例,讲述整个流程:
可以看出,里面是多个算法包互相调用的,且有较多的非
.py
文件
3.1 Dockerfile
FROM python:3.6 # 导入python3.6基础环境
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime\
&& echo 'Asia/Shanghai'>/etc/timezone # 同步系统时间
COPY ./ ./app/ # 将算法里面的所有文件和文件夹复制到镜像里
WORKDIR /app/ # 设置镜像里的app为主文件夹
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 将算法需要的包在镜像中进行安装
RUN pyarmor obfuscate --recursive myprocessor.py # 对所有算法递归加密
RUN ls # 显示app内的所有文件
CMD ["python3","/app/dist/myprocessor.py"] # 运行dist内的加密后的主函数
3.2 requirements.txt
# 这里就是运行我的算法依赖的模块,pyarmor==7.4.2一定要加,其他的根据自己的算法依赖添加
pyarmor==7.4.2
pandas == 1.1.5
numpy == 1.19.5
requests == 2.25.1
3.3 加密函数lock_by_pyarmor.py
# -*- coding: utf-8 -*-
import shutil
import os
class File_lock():
def __init__(self):
self.root_path = os.getcwd() # 当前工作路径
def remove_and_del_unsecret_dir_f(self):
'''移除未加密的py和pyc文件,复制非py,pyc文件到dist'''
for root, dir, files in os.walk(self.root_path):
if "dist" not in root:
for file in files:
if os.path.splitext(file)[-1] in ['.py', '.pyc']:
# 删除所有未加密的.py和.pyc文件
os.remove(os.path.join(root, file))
else:
# 由于非py文件无法加密,因此将非py文件移动到同名文件夹下,若找不到同名文件夹就创建同名文件夹
if root == self.root_path:
dist_same_die_path = os.path.join(self.root_path, 'dist')
else:
dist_same_die_path = os.path.join(self.root_path, 'dist', os.path.basename(root))
if not os.path.exists(dist_same_die_path):
os.mkdir(dist_same_die_path)
shutil.move(os.path.join(root, file), dist_same_die_path)
temp_list = os.listdir() # 移除dist外的所有空文件夹
temp_list.remove('dist')
for i in temp_list:
os.rmdir(i)
def lock_by_pyarmor(self):
# print("当前工作路径:",self.root_path)
# print("os.listdir", os.listdir())
if (not os.path.exists(os.path.join(self.root_path, "dist"))): # 若dist不存在
os.system("pyarmor obfuscate --recursive myprocessor.py") # 加密
self.remove_and_del_unsecret_dir_f()
else:
# print("加密后文件夹:",os.listdir())
self.remove_and_del_unsecret_dir_f()
# print("移除未加密文件后:",os.listdir())
3.4 主函数myprocessor.py
from lock_by_pyarmor import File_lock
def call(arg, model, *args, **kwargs):
lockf = File_lock()
lockf.lock_by_pyarmor()
from deviation_algothrim.get_deviation import Deviation
from loss_power.get_loss_power import GetPower
pass
if __name__ == "__main__":
print(call(arg=None, model=None))
注意:从其他包里导入需要的内容,需要放到
lockf.lock_by_pyarmor()
之后,不然,还没有完全构建成dist文件,可能会调用报错。
3.5 创建镜像并验证效果
docker build _t imag1 .建立完镜像后,app内目录为:
docker run -d imag1 /bin/bash -c "tail -f /dev/null"
docker ps #找到正在运行的容器id
docker exec -it 2293ee92f3ca /bin/bash # 进入容器
python /app/dist/myprocessor.py # 执行加密文件
可以看到app内只剩下了dist文件。
最后需要将启动的容器重新打包成镜像,并发布到harbor上:docker commit 2293ee92f3ca7 new_image,丢弃原本的镜像。因为原本镜像中是有未加密文件的,并且可以访问 。
可以将容器里的加密文件导出到本地D盘: docker cp bf5f2e815b64:/app D:/
ps: 如有问题,或者lock_by_pyarmor.py有更好的实现方法,希望可以指正。
来源:https://blog.csdn.net/qq_34229228/article/details/125102087


猜你喜欢
- TypeScript打包 webpack整合通常情况下,实际开发中我们都需要使用构建工具对代码进行打包;TS同样也可以结合构建工具
- 一,子选择基本用法 1,子选择的定义 子迭择允许把一个查询嵌套在另一个查询当中。比如说:一个考试记分项目把考试事件分为考试(T)和测验(Q)
- 希腊Web 设计师Christos Chiotis 发表在 CssGlobe 的一篇文章,讲述了黄金分割率在 CSS 中的应用。黄金分割率是
- 要绘制单个点,可使用函数scatter(),并向其传递一对x和y坐标,它将在指定位置绘制一个点:"""使用sc
- 主要是要注意权限的问题,一般做发布/订阅,建议你做如下准备工作: 1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的
- 在Django中对于基于函数的视图我们可以 @csrf_exempt 注解来标识一个视图可以被跨域访问。那么对于基于类的视图,我们应该怎么办
- 前言本文主要给大家介绍了关于python中reload(module)用法的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细
- 以下介绍用数据库实现简单计数器,功能实现统计网站每日访问,每周访问及总访问量的统计,使用js调用下面存为count.asp<%&nbs
- 继Go 1.18支持泛型后,Go 将在下个版本中支持pdqsort排序算法再次引起了开发者们的热切讨论。目前,Go仓库的最新commit中提
- 一、介绍正则表达式是一个特殊的字符序列,计算机科学的一个概念。通常被用来检索、替换那些符合某个模式(规则)的文本。许多程序设计语言都支持利用
- 很多的网站都有记数器,用来记录网站的访问量,这给网站管理员即时了解本网站的运行及访问情况提供了很多的方便。笔者研究过很多用ASP编写的计数器
- 1、git merge冲突了,根据提示找到冲突的文件,解决冲突如果文件有冲突,那么会有类似的标记2、修改完之后,执行git add 冲突文件
- 一、前言我用的是面向对象写的,把界面功能模块封装成类,然后在客户端创建对象然后进行调用。好处就是方便我们维护代码以及把相应的信息封装起来,每
- 本文记录了NLTK 3.2.4 环境搭建的方法,供大家参考,具体内容如下系统环境:win7 32位python:2.7.13,后改为3.6.
- apache对php的支持是通过apache的mod_php5模块来支持的,这点与nginx不同。nginx是通过第三方的fastcgi处理
- 现在我将清除页面缓存的一些方法总结如下:1、在Asp页面首部加入<% Response.Buffer = True
- 在学习OpenCV或者其他关于Python技术的时候,我们通常需要准备不同的Python环境,我选择了Anaconda作为我的Python环
- import osimport sysimport MySQLdbdef getStatus(conn):  
- I/O吞吐量小,形成了瓶颈效应。 没有创建计算列导致查询不优化。 内存不足。 网络速度慢。 查询出的数据量过大(可以采用多次查询,其他的方法
- 一、名称空间和作用域1、命名空间(Namespace)命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。命