Python代码加密方案

方案1:使用Pyarmor工具进行加密

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

1、安装
pip install pyarmor

# 验证是否安装成功, 7.0 以下版本为稳定版
pyarmor --version
2、加密过程
  • 首先把源代码编译成代码块

    char *filename = "foo.py";
    char *source = read_file( filename );
    PyCodeObject *co = Py_CompileString( source, "<frozen foo>", Py_file_input );
    
  • 接着进行如下处理

    1. 使用 try...finally 语句把代码块的代码段 co_code 包裹起来
    新添加一个头部,对应于 try 语句:
    
            LOAD_GLOBALS    N (__armor_enter__)     N = length of co_consts
            CALL_FUNCTION   0
            POP_TOP
            SETUP_FINALLY   X (jump to wrap footer) X = size of original byte code
    
    接着是处理过的原始代码段:
    
            对于所有的绝对跳转指令,操作数增加头部字节数
    
            加密修改过的所有指令代码
    
            ...
    
    追加一个尾部,对应于 finally 块:
    
            LOAD_GLOBALS    N + 1 (__armor_exit__)
            CALL_FUNCTION   0
            POP_TOP
            END_FINALLY
    
    1. 添加字符串名称 __armor_enter, __armor_exit__ 到 co_consts

    2. 如果 co_stacksize 小于 4,那么设置为 4

    3. 在 co_flags 设置自定义的标志位 CO_OBFUSCAED (0x80000000)

    4. 按照上面的方式递归修改 co_consts 中的所有类型为代码块的常量

  • 然后把改装后的代码块转换成为字符串,把字符串进行加密,保护其中的常量和字符串

    char *string_code = marshal.dumps( co );
    char *obfuscated_code = obfuscate_algorithm( string_code  );
    
  • 最后生成加密后的脚本,写入到磁盘文件

    sprintf( buf, "__pyarmor__(__name__, __file__, b'%s')", obfuscated_code );
    save_file( "dist/foo.py", buf );
    
3、加密模式

PyArmor 提供多种加密模式,以满足安全和性能方面的平衡。通常情况下,默认 的加密模式能够满足绝大多数的需要,一般情况下也不需要对加密模式有详细 的了解。仅当对性能有特别的要求或者默认加密模式无法满足需求的时候,才需 要改变加密模式,这就需要理解 PyArmor 的不同加密模式。

  • 默认加密模式

    加密脚本命令

    pyarmor obfuscate xx.py

  • 超级模式

    目前支持版本

    1. python 2.7

    2. python 3.7

    加密脚本命令

    pyarmor obfuscate --advanced 2 xx.py

  • 高级模式

    加密脚本命令

    pyarmor obfuscate --advanced 1 xx.py

  • 其他加密模式(不常用)

    1. 代码加密模式

    2. 代码包裹模式

    3. 模块加密模式

    4. 约束模式

4、使用pyarmor
  1. 加密脚本

pyarmor [command] [options]

常用命令:pyarmor obfuscate main.py

pyarmor会加密main.py文件和相同目录下的所有*.py文件,并创建输出子目录dist, 生成加密的主脚本main,py、相同目录下的**.py、生成的运行加密脚本所需的全部辅助文件保存到dis输出目录

  1. 发布加密脚本

发布加密脚本给客户只需要把输出路径dist的所有文件拷贝过去即可

  1. 生成新的许可文件(可选)

使用命令 licenses为加密脚本生成新的许可文件license.lic,加密脚本的同时会在输出目录下面生成一个默认许可文件,dist/licnese.lic,需要生成新的许可文件,并覆盖默认许可文件

例如:

pyarmor licneses --expired 2019 -01-01 code-001

执行该命令会生成一个带有效期的认证文件,这样超过指定日期后加密脚本就无法正常运行了

  1. 绑定加密脚本到固定机器上(可选)

如果想绑定加密脚本到固定机器上,首先在该机器上面运行下面的命令获取硬件信息

pyarmor hdinfo

然后生成绑定到固定机器的许可文件

pyarmor licenses --bind-disk "100304PBN2081SF3NJ5T" --bind-mac "20:c1:d2:2f:a0:96" code-002,

同样,覆盖默认的许可证,这样加密脚本就只能在指定机器上运行

6、命令手册

点击查看

7、优缺点
  1. 优点
  • 使用方便,加密脚本较快且能一键加密,操作较简单

  • 多种加密模式,满足常规绝大多数的加密要求

  • 有文档支持,对于常见的错误异常可以通过查阅官方文档解决

  • 支持其他功能,例如,检查加密脚本的性能、交叉保护机制

  • 可以设置加密文件有效期及绑定在固定机器上

  1. 缺点
  • 每个大的版本的改动比较大,安装时需要查看官方文档选用合适的版本进行安装

  • 个别版本交叉发布时脚本无法运行,具体查看官方文档

  • 安装python版本时需要开启静态库的共享进行安装,否则会无法加密文件

  • 运行加密文件时的python版需要和加密时的python版本一致

  • pyarmor安装的默认是试用版,对加密文件的大小、模块的函数个数等都有限制,用于商业时需要单独购买

方案2:使用cython进行加密
1、安装
pip install cython
2、加密过程
  • 利用Cython将.py文件编译为.c文件

  • 将.c文件编译为为.so或.pyd文件,linux系统为.so文件,Windows系统为.pyd文件

3、使用Cython
  • 创建setup.py加密指定的python文件

    from distutils.core import setup
    from Cython.Build import cythonize
    setup(ext_modules = cythonize(["main.py"], language_level=3)
    
4、简化Cython加密过程

jmpy3为python的一个第三方库,能够将python代码一键加密为.so或者.pyd文件,支持单个文件加密,整个项目加密,加密后会在项目目录中增加一个dist的文件夹,把源文件替换为加密后的文件即可正常运行

  1. 安装

pip install jmpy3

  1. 切换到项目所在目录,执行以下命令

jmpy -i 项目名称

  1. 发布加密脚本

同样加密后会在项目目录中增加一个dist的文件夹,把源文件替换为加密后的文件即可正常运行

5、优缺点
  1. 优点
  • 通过jmpy3可以实现一键加密,加密较为方便

  • 加密后代码运行效率有所提升

  • 生成.so或.pyd文件难以破解

  1. 缺点
  • 兼容性稍差,对于不同的版本的操作系统,需要重新编译

  • 运行加密文件时的python版需要和加密时的python版本一致

  • 没有官方文档,使用加密后的代码出错后,需要自己排查解决错误

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容