精华内容
下载资源
问答
  • Python代码加密混淆

    千次阅读 2019-07-08 16:20:20
    python作为一种解释型语言,源代码加密本身比较困难。但有时候我们在发布一款python产品时又必须考虑到代码加密性,以避免源代码泄露。为此,我查阅了一些资料,研究了几种python代码加密的常见方式,在此记录一下...

    python作为一种解释型语言,源代码加密本身比较困难。但有时候我们在发布一款python产品时又必须考虑到代码的加密性,以避免源代码泄露。为此,我查阅了一些资料,研究了几种python代码加密的常见方式,在此记录一下。

    源代码加密

    (一)py脚本编译成pyc二进制文件

    编译命令:

        python -m py_compile file.py
    

    pyc文件是一个二进制文件,但是可以被很轻松的被逆向,在线反编译工具:https://tool.lu/pyc/。当然也有针对这个问题的解决方案,解决方案是可以通过修改python源代码中的opcode,然后重新编译py代码,可以一定程度上防止被逆向,因为逆向者需要知道被修改的opcode才能还原出来。如果使用私有的Bytecode指令集,那么通常的Python反汇编器和反编译器无法工作在由你私有Python编译器产生的pyc文件上,也相当于保护了你的Python代码。但是这么做的代价是你的Python应用只能在你的私有Python解释器上运行。(实际在发布一款产品时,并不适用)

    (二)py脚本打包成exe文件

    exe文件针对windows平台使用,一般是使用打包程序(py2exe、PyInstaller等)打包成exe,这些工具用于将一个Python项目打包成单个可执行的文件,方便(在没有Python环境的机器上)使用。但通过压缩包可以方便地得到所有pyc文件或源文件,与C/C++编译生成的可执行文件有本质上的区别,基本上是零保护,所以需要将exe进行加壳操作。

    (三)py脚本编译成c文件(cython)

    用cython将核心代码py模块文件转化成.c文件,再用gcc编译成so(unix)文件,或者将其编译成pyd(windows)文件。

    编译过程:

    1、服务器安装依赖

    pip install python
    yum install python-devel gcc
    

    2、编写setup.py文件,内容如下:

    from distutils.core import setup
    from Cython.Build import cythonize
    setup(
    ext_modules = cythonize("test.py",language_level=2)
    )
    # 批量编译
    setup(
    ext_modules = cythonize(["test.py","test2.py".......],language_level=2)
    )
    

    3、运行以下命令

    python setup.py build_ext —inplace
    

    会生成一个test.so,删除其余文件,直接引用test.so即可(跟引用py文件一样)

    源代码混淆

    除了加密以外,还可以对源代码进行混淆,增加源代码的阅读难度。这个有很多第三方库,我列举几个:
    https://pypi.org/project/pyminifier/
    https://github.com/astrand/pyobfuscate
    http://pyob.oxyry.com/

    pyminifier库用法:

    -----------------------------------------------------
    注:我这有个学习基地,里面有很多学习资料,感兴趣的+Q群:895817687
    -----------------------------------------------------
    
    pyminifier -O test.py >> test_py.py
    pyminifier --replacement-length=1 --obfuscate-builtins --obfuscate-import-methods --obfuscate-variables test.py
    
    展开全文
  • Python代码混淆加密,详细介绍请看博客 https://zfj1128.blog.csdn.net/article/details/102825025
  • ZFJPyMix-Python代码混淆加密

    千次阅读 2019-10-30 18:55:37
    前言 Python作为一门脚本语言,我们可以用它做很多事,比如数据分析、多媒体处理、web开发、网络编程、游戏编程、人工智能等等方面都被...混淆加密 网上有很多混淆的方法和技术,混淆都是为了增加代码的阅读难度...

    更新说明

    https://gitee.com/zfj1128/ZFJPyMix

    ----------------------------------------分割线----------------------------------------

    前言

    Python作为一门脚本语言,我们可以用它做很多事,比如数据分析、多媒体处理、web开发、网络编程、游戏编程、人工智能等等方面都被广泛的应用;如果我们用Python来开发商业化项目的时候,难免会遇到一些闲得蛋疼的小人,总想着来破解你的项目或者软件,来破坏别人的劳动成果;所以针对商业化项目做一些必要的加密和混淆是在所难免的!

    混淆加密

    网上有很多混淆的方法和技术,混淆都是为了增加代码的阅读难度;还有就是加密了,最基本的方法是发布pyc文件, 也就是将所有的.py源文件转换成pyc对外发布;还有一种方案是方案是借助cython. cython可以将python文件转换成c, 并编译成pyd文件;这里我们主要讲的是通过ZFJPyMix来混淆Python源码,以达到增加代码的阅读难度的目的!

    混淆工具

    ZFJPyMix具有混淆文件名、混淆类名、混淆属性变量名、混淆方法名和删除注释来混淆Python源码,具体功能结构图如下:
    在这里插入图片描述

    软件界面

    下载地址

    Gitee: https://gitee.com/zfj1128/ZFJPyMix

    教学视频

    链接:https://pan.baidu.com/s/1MEq-vyt_CMSLBdrI3PT6Yg 密码:tvbr

    界面视图

    在这里插入图片描述
    在这里插入图片描述

    混淆日志

    混淆的部分日志,混淆的时候回通过import logging自动生成混淆日志《ZFJPyMix.log》,便于开发者修改部分报错:
    在这里插入图片描述

    混淆忽略

    如果你在混淆过程中不想某个文件或者文件夹不希望被混淆,可以设置忽略文件或者文件夹,多个文件或者文件夹以‘,’进行分割就行了!
    在这里插入图片描述

    特别说明

    1.使用此软件可能会产生一些小问题,非专业Python开发人员慎用;
    2.一个ZFJPyMix账号只能在一台电脑上使用,即注册电脑;
    3.混淆项目的时候请复制一份新的项目进行混淆,备份原有项目;
    4.本软件旨在混淆加固Python代码,严禁使用本软件从事非法用途;

    部分功能

    ZFJPyMix的所以功能中我需要说明的是变量过滤、方法过滤、类名过滤,我们在混淆过程中如果一些命名会导致系统的方法被混淆掉,或者直接混淆了系统的方法,比如方法:__ init __我们可以通过方法过滤来过滤这个方法,防止被混淆;大家也可以自己添加需要忽略混淆的方法!
    在这里插入图片描述

    使用示例

    原代码:

    # -*- coding: utf-8 -*-
    # @Author: zhangfujie
    # @Date:   2019/10/22
    # @Last Modified by:   zhangfujie
    # @Last Modified time: 2019/10/22
    # @ ---------- DFA过滤算 ---------- 
    import time
    time1 = time.time()
    
    class DFAFilter(object):
    	"""DFA过滤算法"""
    	def __init__(self):
    		super(DFAFilter, self).__init__()
    		self.keyword_chains = {}
    		self.delimit = '\x00'
    
    	# 读取解析敏感词
    	def parseSensitiveWords(self, path):
    		ropen = open(path,'r')
    		text = ropen.read()
    		keyWordList = text.split(',')
    		for keyword in keyWordList:
    			self.addSensitiveWords(str(keyword).strip())
    
    	# 生成敏感词树
    	def addSensitiveWords(self, keyword):
    		keyword = keyword.lower()
    		chars = keyword.strip()
    		if not chars:
    			return
    		level = self.keyword_chains
    		for i in range(len(chars)):
    			if chars[i] in level:
    				level = level[chars[i]]
    			else:
    				if not isinstance(level, dict):
    					break
    				for j in range(i, len(chars)):
    					level[chars[j]] = {}
    
    					last_level, last_char = level, chars[j]
    
    					level = level[chars[j]]
    				last_level[last_char] = {self.delimit: 0}
    				break
    			if i == len(chars) - 1:
    				level[self.delimit] = 0
    
    	# 过滤敏感词
    	def filterSensitiveWords(self, message, repl="*"):
    		message = message.lower()
    		ret = []
    		start = 0
    		while start < len(message):
    			level = self.keyword_chains
    			step_ins = 0
    			message_chars = message[start:]
    			for char in message_chars:
    				if char in level:
    					step_ins += 1
    					if self.delimit not in level[char]:
    						level = level[char]
    					else:
    						ret.append(repl * step_ins)
    						start += step_ins - 1
    						break
    				else:
    					ret.append(message[start])
    					break
    			start += 1
    
    		return ''.join(ret)
    

    混淆后的代码:

    import time
    OOO00OOOO0OOOO00O000O = time.time()
    class O00000O00OOOOO00O0OO(object):
    	def __init__(self):
    		super(O00000O00OOOOO00O0OO, self).__init__()
    		self.OOOO0O00OO0OO00OOO0OO = {}
    		self.O0O0OO00O0OO0OO0OOOO0 = '\x00'
    	def O0O00OO0O0OO00O000O0OO(self, path):
    		OO0OO0O0OOOOOO0OOOOO0 = open(path,'r')
    		text = OO0OO0O0OOOOOO0OOOOO0.read()
    		OOOOO00000000OOOO00OO = text.split(',')
    		for O00O0OO0OO0OO0OOOOO0O in OOOOO00000000OOOO00OO:
    			self.O0OOOO0OO0OOOOOOO00OO0(str(O00O0OO0OO0OO0OOOOO0O).strip())
    	def O0OOOO0OO0OOOOOOO00OO0(self, O00O0OO0OO0OO0OOOOO0O):
    		O00O0OO0OO0OO0OOOOO0O = O00O0OO0OO0OO0OOOOO0O.lower()
    		OO0OOO0OOOO0O0OOO0O00 = O00O0OO0OO0OO0OOOOO0O.strip()
    		if not OO0OOO0OOOO0O0OOO0O00:
    			return
    		O0OOOO00OO0OOO0000O0O = self.OOOO0O00OO0OO00OOO0OO
    		for i in range(len(OO0OOO0OOOO0O0OOO0O00)):
    			if OO0OOO0OOOO0O0OOO0O00[i] in O0OOOO00OO0OOO0000O0O:
    				O0OOOO00OO0OOO0000O0O = O0OOOO00OO0OOO0000O0O[OO0OOO0OOOO0O0OOO0O00[i]]
    			else:
    				if not isinstance(O0OOOO00OO0OOO0000O0O, dict):
    					break
    				for j in range(i, len(OO0OOO0OOOO0O0OOO0O00)):
    					O0OOOO00OO0OOO0000O0O[OO0OOO0OOOO0O0OOO0O00[j]] = {}
    					last_level, last_char = O0OOOO00OO0OOO0000O0O, OO0OOO0OOOO0O0OOO0O00[j]
    					O0OOOO00OO0OOO0000O0O = O0OOOO00OO0OOO0000O0O[OO0OOO0OOOO0O0OOO0O00[j]]
    				last_level[last_char] = {self.O0O0OO00O0OO0OO0OOOO0: 0}
    				break
    			if i == len(OO0OOO0OOOO0O0OOO0O00) - 1:
    				O0OOOO00OO0OOO0000O0O[self.O0O0OO00O0OO0OO0OOOO0] = 0
    	def OO0000OOOO0OO00OOOO000(self, O0OOO00O0OO00OOO0O0O0, repl="*"):
    		O0OOO00O0OO00OOO0O0O0 = O0OOO00O0OO00OOO0O0O0.lower()
    		O0OO0OOOOO00OOOOO0000 = []
    		OOOOO0OO000OO0O0O00O0 = 0
    		while OOOOO0OO000OO0O0O00O0 < len(O0OOO00O0OO00OOO0O0O0):
    			O0OOOO00OO0OOO0000O0O = self.OOOO0O00OO0OO00OOO0OO
    			OOOO000O0OO0O000OO00O = 0
    			OO0O000O00O00OO00OO00 = O0OOO00O0OO00OOO0O0O0[OOOOO0OO000OO0O0O00O0:]
    			for O0OOOO00OO0OOOOOO0O0O in OO0O000O00O00OO00OO00:
    				if O0OOOO00OO0OOOOOO0O0O in O0OOOO00OO0OOO0000O0O:
    					OOOO000O0OO0O000OO00O += 1
    					if self.O0O0OO00O0OO0OO0OOOO0 not in O0OOOO00OO0OOO0000O0O[O0OOOO00OO0OOOOOO0O0O]:
    						O0OOOO00OO0OOO0000O0O = O0OOOO00OO0OOO0000O0O[O0OOOO00OO0OOOOOO0O0O]
    					else:
    						O0OO0OOOOO00OOOOO0000.append(repl * OOOO000O0OO0O000OO00O)
    						OOOOO0OO000OO0O0O00O0 += OOOO000O0OO0O000OO00O - 1
    						break
    				else:
    					O0OO0OOOOO00OOOOO0000.append(O0OOO00O0OO00OOO0O0O0[OOOOO0OO000OO0O0O00O0])
    					break
    			OOOOO0OO000OO0O0O00O0 += 1
    		return ''.join(O0OO0OOOOO00OOOOO0000)
    

    结束语

    欢迎过往大牛针对ZFJPyMix提供宝贵的建议和意见!也欢迎大家进QQ群交流学习!
    最后我想说,我们作为程序员应该尊重别人的劳动成果,尊重版权!

    展开全文
  • 为了增加代码阅读的难度, 源代码混淆非常必要, 一个在线的Python代码混淆网站. http://pyob.oxyry.com/ 同时需要注意的是, 这个混淆其实还是被很多人怀疑的, 因为即使混淆了, 也没有改变代码的结构. 这种方法只能...

    动机

    Python进行商业开发时, 需要有一定的安全意识, 为了不被轻易的逆向. 混淆和加密就有所必要了.

    混淆

    为了增加代码阅读的难度, 源代码的混淆非常必要, 一个在线的Python代码混淆网站. http://pyob.oxyry.com/

    同时需要注意的是, 这个混淆其实还是被很多人怀疑的, 因为即使混淆了, 也没有改变代码的结构. 这种方法只能”防君子,不防小人“

    所以, 必要的话, 在编程的时候, 可以故意做点提高逆向难度的事情:

    结构稍微改变, 合并几个类到同一个文件.

    面向对象的结构中, 偶尔穿插一些无伤大雅的范式编程风格.

    加密

    1. 最基本的方法是发布pyc文件, 也就是将所有的.py源文件转换成pyc对外发布. pyc有一个局限性是依赖于python解析器的版本, 使用某一个版本的python解释器生成的pyc必须要在相同版本下的python解释器下才可以正常工作.

    使用上述方法可以方便的生成pyc, 初步的隐藏代码了. 不过pyc依然可以被容易的破解

    1. 另一种方案是借助cython. Cython是属于PYTHON的超集,cython可以将python文件转换成c, 并编译成pyd文件. 一般将核心模块编译成pyd, 这样被破解的风险就大大降低了. 优势:资源丰富,适合快速开发。翻译成C后速度比较快。缺点是:无法支持JIT技术(导致纯python的执行速度比JAVA、JAVASCRIPT等要慢,于是有了PyPy)

    有一个经验之谈, 你可以将所有每个模块中的某个一个位置的变量抽出, 放到一个python文件中, 使用cython来处理这个文件. 这样就会增加破解者从其他pyc文件中移除pyd文件依赖的难度了.

    总结

    作为一门解释型的语言,加密的难度超级大的,开源代码是王道, 但是遇到非加密不可情况, 可以选择上面的加密方法或者混淆方法

    展开全文
  • 介绍Python代码混淆工具,可以对源代码进行混淆处理,保证功能不变但代码基本不可读。 注意大部分混淆工具都是可逆的,例如编译生成pyc文件可以用https://github.com/wibiti/uncompyle2来解码。 pyminifier ...

    有时候用Python开发一些功能但不希望用户得到源代码,就希望对Python代码加一些保密措施。目前可行的方案可能是将核心代码用cython编译成os文件。分析如下:

    1.用pyc或pyo文件代替
    生成方式看这里。Python作为脚本语言,基本上只要是能得到pyc或pyo文件,便是等于拿到了源码,比如python在线反编译可以通过pyc和pyo文件快速识别出源代码。所以此方法只能隐藏源码。

    2.混淆源代码
    比如这里提供了在线的Python代码混淆服务,一定程度上增加了破解者阅读代码的成本,但是仍然不能起到保密的作用。

    3.pyexe、PyInstaller、py2app等打包软件
    这些工具用于将一个Python项目打包成单个可执行的文件,方便(在没有Python环境的机器上)使用。但通过压缩包可以方便地得到所有pyc文件或源文件,与C/C++编译生成的可执行文件有本质上的区别,基本上是零保护。

    4.Cython
    Cython是属于PYTHON的超集,他首先会将PYTHON代码转化成C语言代码,然后通过c编译器生成可执行文件。优势:资源丰富,适合快速开发。翻译成C后速度比较快。缺点是:无法支持JIT技术(导致纯python的执行速度比JAVA、JAVASCRIPT等要慢,于是有了PyPy)
    ————————————————
    版权声明:本文为CSDN博主「孤独な旅人」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kmsj0x00/article/details/80050912

    简介

    介绍Python代码混淆工具,可以对源代码进行混淆处理,保证功能不变但代码基本不可读。

    注意大部分混淆工具都是可逆的,例如编译生成pyc文件可以用 https://github.com/wibiti/uncompyle2 来解码。

    pyminifier

    pyminifier是一个对Python文件进行压缩、混淆的工具,项目地址 https://github.com/liftoff/pyminifier 。

    使用方式比较简单,通过pip安装。

    pip install pyminifier

    然后直接运行命令,把混淆后的输出重定向文件即可。

    pyminifier ./sparse_classifier.py > new.py

    默认命令只是对代码顺序进行重排和减少注释,如果需要混淆代码需要加上参数。

    pyminifier -O ./sparse_classifier.py > new.py

    注意,目前pyminifier只能处理单个文件,而且部分脚本混淆后不可运行,需要手动测试。

    Oxyry Python Obfuscator

    Oxyry Python Obfuscator是一个在线混淆代码的工具,地址是 http://pyob.oxyry.com/ 。

    注意目前Oxyry也只能混淆单个Python文件,测试过混淆后代码可用。

    Opy

    Opy也是一个代码混淆工具,可以对整个目录的Python文件进行混淆处理,并且支持定义混淆格式,项目地址 https://github.com/QQuick/Opy 。

    经过测试,混淆后的Python项目不可直接执行,不建议使用。

    编译成C模块

    目前大部分开源的Python代码混淆工具都是可逆的,最安全的不可逆方式是把Python代码编译成C模块,直接发布编译后的类库即可。

    但需要编写额外的代码来生成C模块,并且生成后的模块不一定可以直接运行。

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 290
精华内容 116
关键字:

python混淆加密代码

python 订阅