Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

Python代码的加密和混淆



当需要发布用Python编写的程序时,保密性往往是需求之一,以避免核心代码的泄露,避免业务功能的实现细节的泄露。

接下来介绍几种方式,包括有效的,和看起来有效实际无效的。

先在同一目录里创建两个测试文件:

# a.py
class Test:
  def add(self, i, j):
    return i+j
  def divide(self, i, j):
    return i/j

# b.py
from a import Test

t = Test()
print(t.add(1,3))
print(t.divide(9,3))

加密

这里再回顾一下python的一些文件类型:

.py: python的源码文件.
.pyc: Python源码import模块后,编译生成的字节码.
.pyo: Python源码编译优化生成的字节码。pyo比pyc并没有优化多少,只是去掉了断言.
.pyd: Python的动态链接库(Windows平台).

将python源码编译为.so文件或者windows上的.pyd文件(可行)

上面的两个测试文件是b文件调用a文件的类,于是可以将a文件编译为.so或.pyd格式。

先安装cython

pip install cython

在当前目录添加一个setup.py:

from distutils.core import setup
from Cython.Build import cythonize
setup(
    ext_modules = cythonize("a.py")
)

接着运行:

python setup.py build_ext --inplace

此时在当前目录能看到编译后的文件和中间文件,比如a.c、a.so。

现在只保留a.so和b.py,然后运行python b.py仍然能正常运行,不过a.py中的内容已对外保密了。

windows上也是类似的操作,如果遇到错误提示"error: Unable to find vcvarsall.bat",那么需要安装vc,到这个链接里: The latest supported Visual C++ downloads

 

将python源码转换为字节码即.pyc文件(不可行)

在python文件调用模块时,被调用的模块会先解释为字节码并存于.pyc文件中,以提高效率。也可以指定将所有文件都转换为字节码。

但是字节码并不安全,可以轻易地查看.pyc文件中的字节码的操作指令,也能将pyc文件重新转回py文件。

关于pyc文件可以看这篇:理解Python中的字节码

 

将python源码打包为windows上的exe文件(不可行)

可以用pyinstaller或py2exe将python文件打包,但是这只是方便了去除环境依赖的运行,并不对安全产生作用。

exe文件看似保密,但实际上仍可以通过解压等方式获得源码。于是需要对exe文件进行加壳操作(未尝试)。或者转换为pyd文件后统一打包为exe文件才行。

 

代码混淆

代码混淆是将原文件转换为功能上不变,但是难以阅读理解的文件。

这样代码仍然可以被执行,但其中的细节却无法轻易复制。

比如可以是将变量、函数、类名变成无意义的名字,甚至于加上特殊字符。或者以一定规则插入无意义的字符,这样不知晓规则的人就无从获得原来代码的样子。

可以用pyminifier来做代码混淆。

pip install pyminifier

比如现在随便用几句python语句试试,原文件内容是:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

topic_url = "https://www.zhihu.com/topic/19552832/hot"
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
chrome_driver = "./chromedriver"
driver = webdriver.Chrome(chrome_driver, chrome_options=chrome_options)
driver.get(topic_url)
driver.quit()

执行一个简单的命令指定用unicode更改其中的变量:

pyminifier --nonlatin --replacement-length=10 run.py >> run_new.py

新的文件就会变成下面图片这个样子(我也保存不进去了),但这个只是增加了难度,并不意味着绝对安全,并会带来运行和调试的问题。注意多设置一些条件,注意混淆变量名、函数名、类名、内外模块名。未仔细研究了。

下一篇:  Python加Selenium自动化测试知乎网站(四)等待机制
上一篇:  理解Python中的字节码

共有0条评论

添加评论

暂无评论