有些时候我们要在其他服务器部署流程,需要对自己的程序进行加密来保护源码。
脚本加密
Cython加密
先使用cython将源码转为C,然后再编译的加密方法。之后写一个运行脚本通过引用加密后的库来调用里面的函数,再使用Py-Fuscate来混淆这个运行脚本,加大逆向的难度。
cython的使用方式是先编写一个setup脚本如setup.py
from distutils.core import setup
from Cython.Build import cythonize
module = cythonize(['script.py'], build_dir='directory', language_level='3')
setup(ext_modules = module)
然后执行
python setup.py build_ext --inplace
这样,便会把script.py编译生成对应的pyd或so格式(根据系统类型)。然后再编写一个运行脚本来import编译后的pyd或so中的函数,再混淆此脚本
python py_fuscate.py -i run.py -o output_path -c 50
pyarmor加密
相比以上cython加密方式,使用pyarmor更加简便。当然pyarmor也是一种加密和混淆的方式,还是有对应的解包工具的,如PyArmor-Unpacker,不过逆向的难度还是不小的。
# pyarmor加密foo.py和同目录下所有的.py文件
pip install pyarmor
pyarmor gen foo.py
# 加密后的脚本会保存到dist文件夹下
python dist/foo.py
文本加密
有时还需要对用到的一些文本文件进行加密,这里可采用AES-256-GCM进行加密,并把密匙写到脚本中,再对脚本进行加密。
AES-256bit
这里把最终的输出都编码为字符串了,仅适用于我自己的流程。
import base64
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto import Random
# 字符串加密
def encrypt_AES(raw, password):
private_key = hashlib.sha256(password.encode("utf-8")).digest()
raw = pad(raw.encode("utf-8"), 16, style="pkcs7")
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_GCM, iv)
encrypt_data = base64.b64encode(iv + cipher.encrypt(raw))
return encrypt_data.decode("utf-8")
# 字符串解密
def decrypt_AES(enc, password):
enc = enc.encode("utf-8")
unpad = lambda x: x[: -ord(x[len(x) - 1:])]
private_key = hashlib.sha256(password.encode("utf-8")).digest()
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_GCM, iv)
unppad = unpad(cipher.decrypt(enc[16:]))
return unppad.decode("utf-8")
# 文本文件加密
def file_encrypt_AES(inputFile, outputFile, password):
input = open(inputFile, "r", encoding="utf-8")
output = open(outputFile, "w", encoding="utf-8")
for line in input:
encryptString = encrypt_AES(line.strip(), password)
output.write(encryptString + "\n")
input.close()
output.close()
# 文本文件解密
def file_decrypt_AES(inputFile, outputFile, password):
input = open(inputFile, "r", encoding="utf-8")
output = open(outputFile, "w", encoding="utf-8")
for line in input:
outputString = decrypt_AES(line.strip(), password)
output.write(outputString + "\n")
output.close()
input.close()
# 读取加密的文本文件
def file_decrypt_read_AES(inputFile, password):
input = open(inputFile, "r", encoding="utf-8")
lineList = []
for line in input:
outputString = decrypt_AES(line.strip(), password)
lineList.append(outputString)
input.close()
return lineList