亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一種Python工具的License授權(quán)機(jī)制詳解

 更新時(shí)間:2023年06月14日 09:35:30   作者:李艷青 1987  
這篇文章主要介紹了一種Python工具的License授權(quán)機(jī)制,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一種Python工具的License授權(quán)機(jī)制

作為一種流行語言,在不同的應(yīng)用領(lǐng)域,利用Python書寫的工具越來越多。

Python具有應(yīng)用領(lǐng)域廣泛、簡單易學(xué)、功能強(qiáng)大等特點(diǎn),但是在很多場合它也具有一些較難克服的缺點(diǎn):

  • 代碼明文,較難加密。
  • 由于#1,python腳本很難應(yīng)用于收費(fèi)工具領(lǐng)域。

那么如果我想對一個Python工具的使用加以限制,有沒有什么方法可以實(shí)現(xiàn)呢?本文提供一種簡易的License授權(quán)機(jī)制實(shí)現(xiàn)思路,它主要包括如下幾部分內(nèi)容:

  • 如何生成一個加密的License文件。
  • 如何做License內(nèi)容核驗(yàn)。
  • 如何加密Python代碼。

其主要流程邏輯如下

圖1 License授權(quán)機(jī)制流程

一、引題

我寫了一個python腳本eda.py,內(nèi)容如下。

#!/usr/bin/env python3
def function():
    print('I am an EDA tool!')
function()

我在Linux操作系統(tǒng)中執(zhí)行了這個程序,成功了,輸出如下。

[liyanqing@ic001 license]$ ./eda.py
 
I am an EDA tool!

我決定把這個“牛逼”的腳本分享給別人使用。但是主要的障礙在于,我不希望別人隨便傳播這個腳本,不希望別人無限期使用這個腳本,不希望別人學(xué)會這幾行代碼的寫法,于是我決定對它加上License限制。

二、生成License文件

工具License常在如下方面對工具的使用加以限制:

  • 使用的MAC地址。(防止工具被隨意拷貝使用)
  • 使用期限。(過期失效)

更加復(fù)雜的應(yīng)用場景,還可以對License使用數(shù)量、用戶列表、工具feature等因素加以限制。

按照這個需求,我們要設(shè)計(jì)一個簡化的License文件,它需要包含以下內(nèi)容:

  • MAC :允許工具啟動的機(jī)器的MAC地址。
  • Date :工具有效期。
  • Sign :簽名,對以上明文內(nèi)容的加密,用作內(nèi)容核驗(yàn)。


首先,我們可以用下面的Linux指令獲取機(jī)器的MAC地址。

[liyanqing@ic001 license]$ ifconfig -a
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.246.128  netmask 255.255.255.0  broadcast 192.168.246.255
        inet6 fe80::7e02:97:820d:1bd3  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:4a:d4:6c  txqueuelen 1000  (Ethernet)
        RX packets 1491722  bytes 1542769755 (1.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 533500  bytes 32951033 (31.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

在centos7系統(tǒng)下,可以從ether行抓取機(jī)器的MAC地址。其他的操作系統(tǒng)略有不同。

我們限制工具的使用期限,比如2021.05.20。

最后我們將如上信息加密。

常見的加密算法有AES(對稱加密)和RSA(非對稱加密),其中AES因執(zhí)行速度快和硬件支持(部分Intel的處理器支持ASE指令加速)常用作批量內(nèi)容的數(shù)據(jù)加密,RSA則由于其公鑰-私鑰機(jī)制常用于秘鑰傳輸。此處我們選擇AES加密方式來加密MAC /Date信息。

下面直接給出生成License文件的腳本gen_license_file.py。

#!/usr/bin/env python3
from Crypto.Cipher import AES
from binascii import b2a_hex
def encrypt(content):
    # content length must be a multiple of 16.
    while len(content) % 16:
        content += ' '
    content = content.encode('utf-8')
    # Encrypt content.
    aes = AES.new(b'2021052020210520', AES.MODE_CBC, b'2021052020210520')
    encrypted_content = aes.encrypt(content)
    return(b2a_hex(encrypted_content))
def gen_license_file():
    license_file = './License.dat'
    with open(license_file, 'w') as LF:
        LF.write('MAC : 00:0c:29:4a:d4:6c\n')
        LF.write('Date : 20210520\n')
        sign = encrypt('00:0c:29:4a:d4:6c#20210520')
        LF.write('Sign : ' + str(sign.decode('utf-8')) + '\n')
if __name__ == '__main__':
    gen_license_file()

            

我們利用這個腳本可以生成一個添加了限定條件的License文件。

[liyanqing@ic001 license]$ ./gen_license_file.py
[liyanqing@ic001 license]$ cat License.dat
MAC : 00:0c:29:4a:d4:6c
Date : 20210520
Sign : 6ccda9297714c2b0c9877625ad6d38aacae4d6d97a0652c926c11ff42fc30d1c

其中Sign部分是以上明文信息的加密,用作校驗(yàn)。

三、核驗(yàn)license文件

在原始的eda.py腳本中,我們需要載入這個License文件,并做如下幾件事情:

  • 解析License文件,獲取MAC/Date/Sign信息。
  • 解密Sign信息。
  • 對比解密的Sign信息和MAC/Date信息,看License文件是否被篡改。
  • 獲取當(dāng)前機(jī)器MAC信息和當(dāng)前Date信息。
  • 將當(dāng)前機(jī)器MAC信息和當(dāng)前Date信息同Sign的解密信息核驗(yàn),看是否超限。

那么我們把如上的License核驗(yàn)步驟加入到eda.py中,得到了新的代碼如下。

#!/usr/bin/env python3
import os
import re
import sys
import datetime
import subprocess
from Crypto.Cipher import AES
from binascii import a2b_hex
## License check
def license_check():
    license_dic = parse_license_file()
    sign = decrypt(license_dic['Sign'])
    sign_list = sign.split('#')
    mac = sign_list[0].strip()
    date = sign_list[1].strip()
    # Check license file is modified or not.
    if (mac != license_dic['MAC']) or (date != license_dic['Date']):
        print('*Error*: License file is modified!')
        sys.exit(1)
    # Check MAC and effective date invalid or not.
    if len(sign_list) == 2:
        mac = get_mac()
        current_date = datetime.datetime.now().strftime('%Y%m%d')
        # Must run this script under specified MAC.
        if sign_list[0] != mac:
            print('*Error*: Invalid host!')
            sys.exit(1)
        # Current time must be before effective date.
        if sign_list[1] > current_date:
            print('*Error*: License is expired!')
            sys.exit(1)
    else:
        print('*Error*: Wrong Sign setting on license file.')
        sys.exit(1)
def parse_license_file():
    license_dic = {}
    license_file = './License.dat'
    with open(license_file, 'r') as LF:
        for line in LF.readlines():
            if re.match('^\s*(\S+)\s*:\s*(\S+)\s*$', line):
                my_match = re.match('^\s*(\S+)\s*:\s*(\S+)\s*$', line)
                license_dic[my_match.group(1)] = my_match.group(2)
    return(license_dic)
def decrypt(content):
    aes = AES.new(b'2021052020210520', AES.MODE_CBC, b'2021052020210520')
    decrypted_content = aes.decrypt(a2b_hex(content.encode('utf-8')))
    return(decrypted_content.decode('utf-8'))
def get_mac():
    mac = ''
    SP = subprocess.Popen('/sbin/ifconfig', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdout, stderr) = SP.communicate()
    for line in str(stdout, 'utf-8').split('\n'):
        if re.match('^\s*ether\s+(\S+)\s+.*$', line):
            my_match = re.match('^\s*ether\s+(\S+)\s+.*$', line)
            mac = my_match.group(1)
            break
return(mac)
# Main function.
def function():
    print('I am an EDA tool!')
license_check()
function()

執(zhí)行一下,效果如下。

[liyanqing@ic001 license]$ ./eda.py
 
*Error*: License is expired!

License過期了,工具被禁止啟動,限制成功!

四、Python加密

上述的License限制機(jī)制生效了,但是Python工具代碼是明文的,所有的限制都可以通過篡改工具代碼而繞過去,頭疼。

為此我們需要將Python工具代碼加密,才能保證License的實(shí)現(xiàn)機(jī)制不被隨便篡改。

Python代碼常見的5中加密機(jī)制如下:

1. 將.py文件轉(zhuǎn)為.pyc文件,.pyc文件是二進(jìn)制文件,不具備可讀性,從而實(shí)現(xiàn)了代碼隱藏。

問題:.pyc文件很容易被反編譯,python有一個庫compileall就可以輕松實(shí)現(xiàn)。

2. 代碼混淆。

問題:只是降低了代碼可讀性,并不能完全隱藏代碼邏輯和核心內(nèi)容的明文信息。

3. 通過py2exe將python代碼打包成二進(jìn)制可執(zhí)行文件。

問題:只能在windows平臺上使用。

4. 使用Cython將.py文件編譯.so文件,內(nèi)容就被加密了且較難破解。

問題:部分代碼可能存在不兼容的問題。

5. 修改Python解釋器。

問題:難度太高!

考慮到加密效果,綜合考量實(shí)現(xiàn)難度,我們選擇#4基于Cython的加密方案。

基于Cython的加密方案需要注意兩點(diǎn):

.so文件可以被Python文件import,但是不可以直接運(yùn)行。執(zhí)行Cython加密腳本的Python版本需要同執(zhí)行Python工具的Python版本保持一致,能夠顯著減少代碼兼容性問題。

第一步,我們需要改造eda.py,將核心代碼移到新文件(比如top.py),頂層腳本eda.py只保留一個空殼,同時(shí)把核心功能通過import的方式引入。

改造后,核心腳本top.py的內(nèi)容如下。同原先的eda.py相比,執(zhí)行函數(shù)license_check()和function()被移除了,其它一致。

而改造后的eda.py則成了一個空殼子,如下。

#!/usr/bin/env python3
import top
top.license_check()
top.function()

然后我們嘗試通過Cython將top.py的內(nèi)容加密。這個過程主要是借助Cython和disutils兩個pyton庫來實(shí)現(xiàn)。

首先,我們寫一個setup.py文件。

import os
from distutils.core import setup
from Cython.Build import cythonize
py_files = ['top.py',]
setup(ext_modules = cythonize(py_files),)

然后用指定Python腳本來執(zhí)行setup.py。

[liyanqing@ic001 license]$ python3 setup.py build_ext --inplace
Compiling top.py because it changed.
[1/1] Cythonizing top.py
running build_ext
building 'top' extension
creating build
creating build/temp.linux-x86_64-3.6
gcc -pthread -B /ic/tools/anaconda3/anaconda3.5.2/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/ic/tools/anaconda3/anaconda3.5.2/include/python3.6m -c top.c -o build/temp.linux-x86_64-3.6/top.o
gcc -pthread -shared -B /ic/tools/anaconda3/anaconda3.5.2/compiler_compat -L/ic/tools/anaconda3/anaconda3.5.2/lib -Wl,-rpath=/ic/tools/anaconda3/anaconda3.5.2/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.6/top.o -o /home/liyanqing/test/license/top.cpython-36m-x86_64-linux-gnu.so

我們看到新生成了.c .so文件和build目錄,其中只有.so文件對我們是有用的。

[liyanqing@ic001 license]$ ls
build  eda.py  gen_license_file.py  License.dat  setup.py  top.c  top.cpython-36m-x86_64-linux-gnu.so  top.py

我們清理無用文件(包括top.py),然后將.so文件更名為top.so(去掉cpython***那一堆字符串)

[liyanqing@ic001 license]$ ls
backup  eda.py  License.dat  top.so

這下清爽多了。

然后重新執(zhí)行eda.py。

[liyanqing@ic001 license]$ ./eda.py
*Error*: License is expired!

Good!還能正常執(zhí)行。

而此時(shí)我們看一下.so文件中的核心代碼。

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^C^@>^@^A^@^@^@ð6^@^@^@^@^@^@@^@^@^@^@^@^@^@è^T^F^@^@^@^@^@^@^@^@^@@^@8^@^G^@@^@%^@$^@^A^@^@^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@l^S^... ...

總結(jié)

既然你們都看不懂這些亂碼,我就放心了,哈哈。

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • pytest進(jìn)階教程之fixture函數(shù)詳解

    pytest進(jìn)階教程之fixture函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于pytest進(jìn)階教程之fixture函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 基于Python制作短信發(fā)送程序

    基于Python制作短信發(fā)送程序

    這篇文章主要為大家詳細(xì)介紹了如何利用Python制作短信發(fā)送程序,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2023-01-01
  • Python retrying 重試機(jī)制的使用方法

    Python retrying 重試機(jī)制的使用方法

    我們在程序開發(fā)中,經(jīng)常會需要請求一些外部的接口資源,而且我們不能保證每次請求一定會成功,所以這些涉及到網(wǎng)絡(luò)請求的代碼片段就需要加上重試機(jī)制。本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-09-09
  • 對python的bytes類型數(shù)據(jù)split分割切片方法

    對python的bytes類型數(shù)據(jù)split分割切片方法

    今天小編就為大家分享一篇對python的bytes類型數(shù)據(jù)split分割切片方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • 基于Python實(shí)現(xiàn)超級瑪麗游戲的示例代碼

    基于Python實(shí)現(xiàn)超級瑪麗游戲的示例代碼

    這篇文章主要介紹了利用python實(shí)現(xiàn)超級瑪麗游戲的示例代碼,幫助大家更好的理解和使用python開發(fā)游戲,感興趣的朋友可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • Python的條件控制?if?語句詳解

    Python的條件控制?if?語句詳解

    Python的?if?語句用來「控制代碼」的執(zhí)行,「判斷條件成立」時(shí)執(zhí)行一段代碼,判斷條件「不成立」時(shí)執(zhí)行另一段代碼,本文就給大家詳細(xì)講講Python的條件控制?if?語句,需要的朋友可以參考下
    2023-08-08
  • python web框架中實(shí)現(xiàn)原生分頁

    python web框架中實(shí)現(xiàn)原生分頁

    這篇文章主要為大家詳細(xì)介紹了python web框架中使用原生分頁的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • python3+PyQt5實(shí)現(xiàn)柱狀圖

    python3+PyQt5實(shí)現(xiàn)柱狀圖

    這篇文章主要為大家詳細(xì)介紹了python3+PyQt5實(shí)現(xiàn)柱狀圖的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • sklearn-SVC實(shí)現(xiàn)與類參數(shù)詳解

    sklearn-SVC實(shí)現(xiàn)與類參數(shù)詳解

    今天小編就為大家分享一篇sklearn-SVC實(shí)現(xiàn)與類參數(shù)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 解決Keras 自定義層時(shí)遇到版本的問題

    解決Keras 自定義層時(shí)遇到版本的問題

    這篇文章主要介紹了解決Keras 自定義層時(shí)遇到版本的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06

最新評論