如何一键保护你的 Python 代码?

为了防止自己的代码被别人随意窃取或滥用,我们在把实际的工具脚本交由实际执行者时,可以采取一系列手段对Python代码进行加密、编译、混淆以保护我们的工程,以免代码内的敏感信息泄漏导致一些不可控的问题。

现介绍以下几种源码保护手段:

1.编译.pyc文件

pyc文件是一种二进制文件,由原生Python文件经过编译后所生成的,py文件编译成pyc文件后加载速度更快而且提高了代码的安全性。pyc的内容与python的版本相关,不同版本编译的pyc文件不一样。

单个pyc文件的生成

一般正常情况下,我们运行py脚本,其包括所依赖的脚本都会在所在目录下自动编译生成.pyc文件。这次我们主要看下如何通过命令方式主动生成.pyc文件,假设你的Python文件名为example.py,它的绝对路径是/path/to/example.py,你可以在命令行中执行以下命令来编译该文件:

python -m py_compile /path/to/example.py #需要提供py文件绝对路径

# pyc会生成在目录下的__pycache__下(前后有双下划线)
# 生成的文件名命名方式:源文件名.cpython-python版本.pyc

批量pyc文件的生成

通过compile_dir方法指定目录,会将其目录下所有py文件全部编译为pyc文件

compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]])

参数含义:
– maxlevels:递归编译的层数
– ddir:If ddir is given, it is prepended to the path to each file being compiled for use in compilation time tracebacks, and is also compiled in to the byte-code file, where it will be used in tracebacks and other messages in cases where the source file does not exist at the time the byte-code file is executed.
– force:如果True,不论是是否有pyc,都重新编译
– rx:一个正则表达式,排除掉不想要的目录
– quiet:如果为True,则编译不会在标准输出中打印信息

python -m compileall <dir>

2.打包为exe

打包Python程序的三方开源库很多,这里主要推荐两种常用且效果不错的打包库:PyInstaller、Nuitka

名称Qt6Qt5WindowsmacOSLinux
PyInstaller部分支持支持支持支持支持
Nuitka支持支持支持支持支持

PyInstaller

PyInstaller是一个第三方库,它能够在Windows、Linux、 Mac OS X 等操作系统下将 Python源文件进行打包,打包完成后,exe即可在没有Python 的环境中运行,也可以作为一个独立文件方便传递和管理。

PyInstaller可以在Windows、Mac OS X和Linux上使用,但是并不是跨平台的,所以打包成.exe文件,需要在Windows系统上运行PyInstaller进行打包工作;打包成mac app,需要在Mac OS上使用。

安装:

pip install pyinstaller

pyinstaller将单个py文件打包

使用:

Pyinstaller -F demo.py -- 打包exe
Pyinstaller -F -w demo.py -- 不带控制台的打包 不带黑框 
Pyinstaller -F -i test.ico demo.py  -- 打包指定exe图标打包

常用选项:
-h,–help	查看该模块的帮助信息
-F,-onefile	产生单个的可执行文件
-D,–onedir	产生一个目录(包含多个文件)作为可执行程序
-a,–ascii	不包含 Unicode 字符集支持
-d,–debug	产生 debug 版本的可执行文件
-w,–windowed,–noconsolc	指定程序运行时不显示命令行窗口(仅对 Windows 有效)
-c,–nowindowed,–console	指定使用命令行窗口运行程序(仅对 Windows 有效)
-o DIR,–out=DIR	指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件
-p DIR,–path=DIR	设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,Linux 使用:号)来分隔多个路径
-n NAME,–name=NAME	指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字
-i	选择图标

在这里插入图片描述

pyinstaller将多个py文件打包

生成spec规范配置文件:

pyi-makespec demo.py

pyinstaller [-F/-D] [-w/-c] [-i xxx.ico] demo.py

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None  #设置 加密,需要安装tinyaes第三方库,最多16位字符,此处在使用--key= 会有变化


a = Analysis(
    ['demo.py'],  # 运行的所有py文件,包括依赖的py文件 
    pathex=[],  # 搜索导入的路径列表(此列表为项目绝对路径),包括选项给出的路径--paths,项目需要从什么地方导入自定义库
    binaries=[],  # 脚本需要的非python模块,包括--add-binary选项给出的名称,二进制数据
    datas=[],  # 应用程序中包含的非二进制文件,包括--add-data选项给出的名称,项目需要用到什么数据,比如图片,视频等。里面格式为tuple,第一个参数是文件路径,第二个是打包后所在的路径,其为一个元组:('image/*.png','data/image')
    hiddenimports=[],   # 假如打包后打开exe显示module not found,就要把该库添加到hiddenimports里面了
    hookspath=[],  
    hooksconfig={},  # 挂钩配置选项由一个字典组成
    runtime_hooks=[],  
    excludes=[],  # 假如你用的python有很多库,但是你不需要用到某个,那么就把它添加到里面去,可以压缩文件大小
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,  # 打包的脚本文件
    # a.binaries,  # 如果是单文件模式,则需要添加;多文件也可以添加
   	# a.zipfiles,
    # a.datas,
    [],
    exclude_binaries=True,  # 是否排除二进制文件,为True时,为排除二进制的文件,当文件交大时包含二进制文件运行较快,如果是单文件,则没有这个选项
    name='demo',  # 打包程序的名字
    debug=False,  # 是否启用调试功能
    bootloader_ignore_signals=False,
    # runtime_tmpdir=None,  # 生成单文件时需要这个参数,定义运行时的临时文件夹
    strip=False,
    upx=True,  # 打包的时候进行压缩,False表示不压缩;要用到一个压缩程序UPX,用于压缩文件,需要单独下载
    console=True,  # 打包后的可执行文件双击运行时屏幕会出现一个cmd窗口,不影响原程序运行,等于是是否加-w参数
    disable_windowed_traceback=False,  
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    
    """添加选项,初始化时没有的"""
    icon="",  # 指定应用程序的图标,传入路径,可以相对路径
    
)
coll = COLLECT(
    """
    如果是单文件模式,不需要这个COLLECT类,同时需要将:
        a.binaries,
    	a.zipfiles,
    	a.datas,
    这些数据文件添加到EXE中
    """
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='main',
)

项目打包:

pyinstaller demo.spec

这样即可将python程序打包成一个独立的应用工具,直接运行即可。实现了保护程序的一个作用(当然也是可以反编译成功的,不过也提升了破解的难度)

Nuitka

nuitka则是将python源码转成C++(这里得到的是二进制的pyd文件,防止了反编译),然后再编译成可执行文件。

安装:

pip install -U nuitka

安装MinGW64:

Windows环境需安装MinGW64,搭建gcc编译环境

MacOS环境不需要单独下载,它会在安装nuitka时自动下载gcc

下载地址:https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/

打包:

nuitka --mingw64 xxx.py # 单纯打包
nuitka --mingw64 --standalone --show-progress --show-memory --enable-plugin=pyqt5 --output-dir=out demo.py  # 指定参数打包

选项说明:
--mingw64:环境选择
--standalone:是否独立环境
--show-progress:展示过程
--show-memory:显示内存
--plugin-enable=qt-plugins:qt配置
--include-qt-plugins=sensible,styles:qt样式保持
--recurse-all:导入引入的资源

nuitka打包并不像网上说的那样,打包速度快,打包体积小。我也实测过,目前体检的感觉就是资源方面的确不用我们考虑那么深,不像pyinstaller可能相关配置就弄好了,打包还是会报资源缺失。而且打包的速度比较慢,体积也挺大的,但是毕竟也是可达到保护Python程序的目的,给使用者方便。

3.代码Obfuscator混淆

借助oxyry在线网站实现obfuscator混淆

在线地址:https://pyob.oxyry.com/

使用 pyobfuscate 库进行混淆

pyobfuscate 会对代码中用户定义的类、函数、变量等进行重命名、更改代码缩进(默认1)、移除注释、添加不影响逻辑的代码语句,最终起到混淆的作用。不过 pyobfuscate 使用 Python2 编写,无法解析 Python3 中的 f-string 等特殊语法,因此使用前需要将源码进行一定程度的修改,当然也可以直接修改 pyobfuscate 库,增加对 Python3 版本的支持。

python pyobfuscate.py demo.py > demo_obfuscated.py

两种主要都是对类和函数名等进行了重置替换,增加阅读难度

4.使用 Cython

使用Cython进行开发

编写文件hello.pyx或hello.py:

def hello():
    print('hello')

编写setup.py:

from distutils.core import setup
from Cython.Build import cythonize

setup(name='Hello World app',
     ext_modules=cythonize('hello.pyx'))

编译为.c,再进一步编译为.so或.pyd:

python setup.py build_ext --inplace

python -c "from hello import hello;hello()"  # 即可直接引用生成的二进制文件中的hello()函数。

生成的二进制 .so 或 .pyd 文件难以破解同时带来了性能提升

5.PyArmor

PyArmor 是一个用于加密和保护 Python 脚本的工具。它能够在运行时刻保护 Python脚本的二进制代码不被泄露,设置加密后 Python 源代码的有效期限,绑定加密后的Python源代码到硬盘、网卡等硬件设备。它的保障机制主要包括:

  • 加密编译后的代码块,保护模块中的字符串和常量

  • 在脚本运行时候动态加密和解密每一个函数(代码块)的二进制代码

  • 代码块执行完成之后清空堆栈局部变量

  • 通过授权文件限制加密后脚本的有效期和设备环境

除了对 Python 代码进行加密,PyArmor 还能设置 Python 程序的许可方式,比如设置程序的使用期限、设置允许运行的设备、扩展其他认证方式等

安装:

pip install pyarmor

使用 obfuscate 选项对代码进行加密:

pyarmor obfuscate demo.py

使用 licenses 选项生成许可文件:

pyarmor licenses \ 
--expired "2023-03-11" \ 
--bind-disk "10030SFTUF3NJ5T" \ 
--bind-mac "56:f1:a7:64:f0:64" \ 
--bind-ipv4 "211.110.6.54" \ 
r001

使用 pack 选项即可打包脚本:

pyarmor pack demo.py

不过这款工具属于试用阶段,倾向于商业模式,可以学习试试。

以上5种方式都可提升程序的安全性,保护项目敏感信息。如果对外发布的,也可提升破解难度。今天的分享就到这里了。

学习资源推荐
除了上述分享,学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述
👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以V扫描下方二维码联系领取
保证100%免费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值