基于Cython和内置distutils库,实现python源码加密(非混淆模式)

起因

python本身只能做混淆,不能加密,多年的商业软件开发导致有某种“洁癖”:欲将py编译打包

尝试

  • pyinstaller原理是freeze打包pyc文件,利用工具可完美逆行出源码
  • 各种混淆脚本,版本兼容很差,配置繁琐
  • cython 常规使用只能编译单个特殊模块

解决

反复尝试摸索后,还是利用了cython和distutils库,自动化识别并转换py到c源码并编译,放出源码供大家参考

""" 
利用cython和distutils编译py到pyd[so] 注意安装cython及本地平台对应编译器
http://flywuya.cnblogs.com/
 """
import os
import shutil
from distutils.core import setup
from distutils.command.build_ext import build_ext
from Cython.Build import cythonize

BUILD_CONFIG = {
    'SupportExt': ['.py', '.pyx'],
    'CopyOnlyFile': ['__main__.py', '__init__.py'],
    'CopyOnlyDir': ['assets'],
    'IgnoreDir': ['dist', 'build', '__pycache__'],
}


def copy_tree(src, dst):
    """ not like shutil.copytree, dst can be exists  """
    assert os.path.exists(src)
    assert os.path.isdir(src)
    os.makedirs(dst, exist_ok=True)

    for fn in os.listdir(src):
        s = os.path.join(src, fn)
        t = os.path.join(dst, fn)
        if os.path.isfile(s):
            shutil.copy2(s, t)
        elif os.path.isdir(s):
            copy_tree(s, t)


def build_module(source_file, dst_dir, tmp_dir):
    """ cythonize && build ext """
    assert os.path.isfile(source_file)
    assert not os.path.isabs(source_file)
    assert os.path.exists(dst_dir)
    os.makedirs(tmp_dir, exist_ok=True)

    build_cython = os.path.join(tmp_dir, 'build.cython')
    build_temp = os.path.join(tmp_dir, 'build.temp')
    build_lib = dst_dir

    ext_modules = cythonize(
        source_file,
        build_dir=build_cython,
        language_level=3,
    )

    class build_here(build_ext):
        def initialize_options(self):
            super().initialize_options()
            self.build_temp = build_temp
            self.build_lib = build_lib
    setup(
        ext_modules=ext_modules,
        script_args=['build_ext'],
        cmdclass=dict(build_ext=build_here)
    )


def build_modules(source_dir, dst_dir, tmp_dir):
    """ scan && build modules in source_dir """
    assert os.path.exists(source_dir)
    assert not os.path.isabs(source_dir)
    assert not os.path.isabs(dst_dir)
    os.makedirs(dst_dir, exist_ok=True)

    for root, dirs, files in os.walk(source_dir):
        rel_pth = root[len(source_dir)+1:]

        for ignore in BUILD_CONFIG['IgnoreDir']:
            if ignore in dirs:
                dirs.remove(ignore)

        for dn in dirs:
            if dn in BUILD_CONFIG['CopyOnlyDir']:
                copy_tree(
                    os.path.join(root, dn),
                    os.path.join(dst_dir, rel_pth, dn)
                )
                dirs.remove(dn)

        for fn in files:
            _, ext = os.path.splitext(fn)
            os.makedirs(
                os.path.join(dst_dir, rel_pth),
                exist_ok=True
            )
            if fn in BUILD_CONFIG['CopyOnlyFile']:
                shutil.copy2(
                    os.path.join(root, fn),
                    os.path.join(dst_dir, rel_pth, fn)
                )
            elif ext.lower() in BUILD_CONFIG['SupportExt']:
                build_module(
                    os.path.join(root, fn),
                    dst_dir,
                    os.path.join(tmp_dir, rel_pth),
                )
            else:
                shutil.copy2(
                    os.path.join(root, fn),
                    os.path.join(dst_dir, rel_pth, fn)
                )


if __name__ == "__main__":

    # 这里填写要编译的目录
    tasks = [
        'app',
    ]

    others = [
        'requirements.txt',
        'packages',
    ]

    BUILD_CONFIG['CopyOnlyFile'].extend(['settings.py'])

    for task in tasks:
        build_modules(
            task,
            os.path.join('dist', task),
            os.path.join('build', task),
        )

    for other in others:
        if os.path.isfile(other):
            bn = os.path.basename(other)
            shutil.copy2(other, os.path.join('dist', bn))
        elif os.path.isdir(other):
            bn = os.path.basename(other)
            copy_tree(other, os.path.join('dist', bn))

转载于:https://www.cnblogs.com/wuyaSama/p/10774094.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#### 介绍 基于Cython的快速国密算法Python实现,目前支持SM2, SM3, SM4(ECB、CBC) #### 安装教程 ``` pip install fastgm ``` #### 使用说明 ##### SM2 SM2是国家密码管理局发布的椭圆曲线公钥密码算法。对标RSA 使用方法: + 生成秘钥 ``` from fastgm import SM2 sk, pk = SM2.generate_key() # sk为私钥,pk为公钥,均为hex格式 ``` + 使用公钥加密 ``` from fastgm import SM2 pk = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207' # 公钥,Hex格式 data = b'helloworld' # 待加密内容,格式为bytes数组 sm2 = SM2() # 初始化 enc = sm2.encrypt(pk, data) # 运行加密算法 ``` + 使用私钥解密 ``` from fastgm import SM2 sk = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5' # 私钥 sm2 = SM2() # 初始化 dec = sm2.decrypt(sk, enc) # 运行解密算法,enc为加密内容 ``` #### SM3 SM3密码杂凑算法是中国国家密码管理局2010年公布的中国商用密码杂凑算法标准。对标MD5 使用方法: ``` from fastgm import SM3 data = b'helloworld' # 待哈希bytes数组 h = SM3().hash(data) # 哈希运算 ``` #### SM4 SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准。对标AES。 -------- 该资内项目码是个人的毕设,代码都测试ok,都是运行成功后才上传资,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值