python代码pyc化加密部署

python不像c,java等编译型语言(编译后发布机器码),解释型则必须把源码发布出去,但仍存在一些交付场景希望能够将python代码加密。

为什么转换为pyc?

  • pyc官方的解释还请自行google
  • 简而言之,pyc文件为字节码文件,单个.py生成.pyc文件后运行效果相同
  • pyc文件运行效率高于py文件(少了解释器对源码的转换)
  • pyc虽然可以进行逆向转换,但不一定可靠(没试过),不过已经满足了简单加密的需求,毕竟源码裸奔交付是心理上不能接收的

如何转换为pyc?

1
python -m compileall (file or dir) -b
  • -b 支持生成pyc文件于当前目录而非__pycache__

配合jenkins进行自动集成发布

  • 基于flask开发目录
1
2
3
4
/app
/conf
/tests
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# /bin/sh

function timeoutController(){
cmd=$1
timeout=$2
mod=$3
count=1
while [ $count -le 3 ]; do
timeout $timeout $cmd
exitCode=$?
if [[ $exitCode == 0 ]] || [[ $exitCode -ne 124 ]]; then
break
fi

if [ $exitCode == 124 ]; then
echo "module: {$mod} timeout {$timeout} s and start to {$count} time retry"
fi
count=`expr $count + 1`
done

if [ $exitCode -ne 0 ]; then
echo $mod "=====================>unittest failed"
exit 1
fi
}

function code_encrypt(){
release_dir=$1
pyc_dir=$2

# release svn del .svn
find $release_dir -name ".svn" | xargs rm -rf

# svn del pyc
cd $pyc_dir
svn rm * --force
svn ci -m "pyc delete"

# cp release code to pyc && encrypt code
cp $release_dir/* $pyc_dir -R
python -m compileall . -b
find . -name "*.py" | xargs rm
rm tests/report -rf
# replace gunicorn.pyc with gunicorn.py
rm $pyc_dir/conf/gunicorn.pyc
cp $release_dir/conf/gunicorn.py $pyc_dir/conf/

# pyc svn commit
svn add . --no-ignore --force
svn ci -m "pyc commit"
}

function main(){
echo "========================== init env ============="
source /root/anaconda3/bin/activate py3
release_dir="/home/pro/pro_release"
pyc_dir="/home/pro/pro_pyc"
release_svn_dir="http://*.*.*.*/"

# update tag:release code
rm $release_dir -rf
svn co $release_svn_dir

echo "========================== flake8 ==============="
cd $release_dir
timeoutController "flake8 --config=${release_dir}/.config/flake8 ${release_dir}" 60 "flake8"

echo "========================== pytest ==============="
cd $release_dir/tests
timeoutController "pytest ."

echo "========================== code encrypt ============="
code_encrypt $release_dir $pyc_dir
}

main
  • 以上脚本基于svn代码管理,如使用git,则flake8,pytest测试可通过git hook,而单单保留代码加密
  • gunicorn 貌似不支持指定pyc为配置文件,但这不影响整体的加密效果,后续可以在研究研究,毕竟对于我这种重度洁癖患者,留这一个.py文件就像一个小疙瘩,总想给它挠掉
-------------The End-------------
坚持原创技术分享,您的支持将鼓励我继续创作!