背景
在一些使用python的商業項目上,開發人員不想被用戶看到源代碼時,就需要對python代碼進行加密;進一步地,如果想限制用戶只能在獲得授權的機器上運行你寫的代碼時(利益相關),就需要使用License控制。只有經過加密的代碼才能進行License控制,試想一下,如果客戶能拿到你的源代碼,那么License控制就成為無稽之談。
這里提供一種代碼加密與License控制的思路。
先說python代碼加密。
代碼加密
眾所周知,python是一種開源的編程語言,在開源的語言上做加密,加密效果肯定不如編譯性語言的加密效果好,其逆向工程的難度會比編譯性語言的逆向工程簡單,按照這個思路,既然編譯性語言c/c++的逆向工程難,那么為何不先把python編譯成c/c++代碼,然后再加密呢?根據經驗這樣是可行的,且這樣加密的代碼比那些編譯成pyd文件或者打包成exe的方法就安全得多(pyd和exe的逆向工程有專門的包可以實現)。這就是這篇文章介紹的加密方法。
思路是先將py轉換為c代碼,然后編譯c為so文件。
準備工作:
linux安裝:
-
python-dev
-
gcc
sudo apt-get install python-dev gcc
python安裝第三方庫
-
pycrypto
(注意:在win10環境下安裝這個包可能會報錯,解決辦法見這里 ) -
Cython
pip install pycrypto Cython
加密腳本``setup.py`的代碼如下
# coding:utf-8
from
distutils
.
core
import
setup
from
Cython
.
Build
import
cythonize
import
os
'''
該文件的執行需要的在Terminal中輸入 python setup.py build_ext --inplace
使用Cpython 編譯python文件,關鍵函數編譯成pyd文件(相當于dll)
'''
# 針對多文件情況設置,單文件就只寫一個就行, 文件之間用逗號隔開
key_funs
=
[
'test.py'
]
setup
(
name
=
"XX app"
,
ext_modules
=
cythonize
(
key_funs
)
,
)
'''
1、將編譯后的pyd文件的命名更改成與原py文件一致
2、刪除編譯后得到的c文件和原py文件
'''
print
(
"——————"
,
os
.
getcwd
(
)
,
"——————"
)
files
=
os
.
listdir
(
os
.
getcwd
(
)
)
print
(
files
)
for
fi
in
files
:
if
fi
.
__contains__
(
".pyd"
)
:
re_name
=
fi
.
split
(
"."
)
[
0
]
+
".pyd"
print
(
re_name
)
os
.
rename
(
fi
,
re_name
)
elif
fi
.
__contains__
(
".c"
)
or
fi
in
key_funs
:
os
.
remove
(
fi
)
為了更好的說明,這里舉個簡單的例子。
另外準備兩個py文件,
test.py
和
main.py
,其中
test.py
是需要加密的代碼,
main.py
是調用加密代碼的腳本,不需要加密。
test.py
的內容如下
import
datetime
class
Today
(
)
:
def
get_time
(
self
)
:
print
(
datetime
.
datetime
.
now
(
)
)
def
say
(
self
)
:
print
(
'hello world'
)
main.py
的內容如下
from
test
import
Today
t
=
Today
(
)
t
.
get_time
(
)
t
.
say
(
)
加密之前,測試一下運行效果,在終端執行
python main.py
,輸出
2019-08-30 11:38:38.419308
hello world
使用
setup.py
對
test.py
進行加密
方法:將需要加密的代碼放到列表
key_funs
里面,然后在終端運行
python setup.py build_ext --inplace
運行完加密腳本
setup.py
后,會將
test.py
刪掉(請備份到其他地方!),得到
test.so
文件和文件夾
build/
,這個文件夾可以刪掉。至此代碼加密完成。
測試
再次在終端執行
python main.py
,輸出
2019-08-30 11:49:17.986503
hello world
成功!
(注意,不能直接在IDE執行main.py,會出現錯誤ImportError: cannot import name ‘Today’)
License控制
知道怎么加密代碼之后,就可以用license控制你的代碼,以防被別人濫用。
通過License可以控制你的代碼,控制方式有很多種,包括限制主機、限制時間(過期則無法執行)、限制使用地點等,這里只介紹如何通過License限制主機,其他方法大同小異,做適當修改即可。
物理地址是每臺計算機獨一無二的身份號碼,我們可以利用物理地址作為限制主機的依據。
具體思路是,用戶拿到你寫的代碼后,如果用戶的計算機未經你權授則不能運行你的代碼,這時候就需要利用物理地址作為權授的載體進行授權計算機。如需要授權計算機,用戶要把需權授的機器的物理地址發給你,你使用AES加密算法把這個物理地址加密后,將得到的加密文件發給用戶(這個加密文件就相當于一把鑰匙,只有擁有這把鑰匙才能正常運行你的代碼)用戶把加密文件放到指定路徑下并執行代碼,程序讀取加密文件并解密,得到你加密的物理地址,將此物理地址與當前主機的物理地址做匹配,如果這兩個物理地址相同則程序能正常運行,不同則退出程序。這里將物理地址加密的目的是防止被用戶篡改。
這里涉及到的加密算法不做詳細介紹,需了解請移步 here
用戶計算機申請授權過程
License控制流程圖
具體代碼及實現例子請移步github
(別忘了點star哦)
Reference:
- 淺談常見的七種加密算法及實現
- 加密Python源代碼筆記
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
