python 的licence授權機制

import re
import datetime
from Crypto.Cipher import AES  #安裝報錯參考 https://blog.csdn.net/pittpakk/article/details/120021977
from binascii import a2b_hex
from binascii import b2a_hex
import sys
import os
import json
import uuid

class get_license_file():
    #生成license
    def __init__(self, mac, deadline_use_time, pwd):
        self.mac = mac
        self.deadline_use_time = deadline_use_time
        self.pwd = pwd

    def encrypt(self, content):
        # content length must be a multiple of 16.
        while len(content) % 16:
            content += ' '
        content = content.encode('utf-8')
        # Encrypt content.
        aes = AES.new(self.pwd.encode(), AES.MODE_CBC, self.pwd.encode())
        encrypted_content = aes.encrypt(content)
        return (b2a_hex(encrypted_content))

    def gen_license_file(self):
        license_file = 'License.dat'
        with open(license_file, 'w') as LF:
            LF.write('MAC : %s\n' % (self.mac))
            LF.write('Deadline_use_time : %s\n' % (self.deadline_use_time))
            sign = self.encrypt('%s#%s' % (self.mac, self.deadline_use_time))
            print('Sign : ' + str(sign.decode('utf-8')) + '\n')
            LF.write('Sign : ' + str(sign.decode('utf-8')) + '\n')

        #生成登陸時間信息
        time_file = 'time.txt'
        current_date = datetime.datetime.now().strftime('%Y%m%d')
        with open(time_file,'w')as f:
            time_sign = self.encrypt('%s'%(current_date))
            data = {"last_use_time": current_date,
                    "deadline_use_time": self.deadline_use_time,
                    "GPU-ID": self.mac,
                    "time_sign":str(time_sign.decode('utf-8'))
                    }
            f.write(json.dumps(data))


class check_license_file():
    #檢測license
    def license_check(self):
        current_date = datetime.datetime.now().strftime('%Y%m%d')
        time_dic = self.parse_time_file()
        last_use_time = time_dic['last_use_time'].strip()
        time_sign = self.decrypt(time_dic['time_sign']).strip()
        # 防止用戶篡改最後登陸時間進行校驗
        if last_use_time != time_sign:
            print('*Error*: Time file is modified')
            sys.exit(1)
        # 防止用戶篡改系統時間進行校驗
        if last_use_time > current_date:
            print('*Error*: The system time has been changed')
            sys.exit(1)

        license_dic = self.parse_license_file()
        sign = self.decrypt(license_dic['Sign'])
        sign_list = sign.split('#')
        mac = sign_list[0].strip()
        date = sign_list[1].strip()

        # 防止用戶篡改過期時間進行校驗
        if (mac != license_dic['MAC']) or (date != license_dic['Deadline_use_time']):
            print('*Error*: License file is modified!')
            sys.exit(1)
        # Check MAC and effective date invalid or not.
        if len(sign_list) == 2:
            mac = self.get_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)
        self.save_time_file(current_date,date,mac)   #更新Json字符串
        print('Succeed')


    def encrypt(self, content):
        # content length must be a multiple of 16.
        while len(content) % 16:
            content += ' '
        content = content.encode('utf-8')
        # Encrypt content.
        aes = AES.new('1122334455667788'.encode(), AES.MODE_CBC, '1122334455667788'.encode())
        encrypted_content = aes.encrypt(content)
        return (b2a_hex(encrypted_content))

    def save_time_file(self,current_date,deadline_use_time,mac):
        #生成time文件
        time_file = 'time.txt'
        with open(time_file, 'w') as f:
            time_sign = self.encrypt('%s' % (current_date))
            data = {"last_use_time": current_date,
                    "deadline_use_time": deadline_use_time,
                    "GPU-ID": mac,
                    "time_sign": str(time_sign.decode('utf-8'))
                    }
            f.write(json.dumps(data))

    def parse_license_file(self):
        #打開文本解析數據
        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 parse_time_file(self):
        time_file = 'time.txt'
        with open(time_file,'r')as f:
            time_sign = json.loads(f.read())
        return time_sign


    def decrypt(self, content):
        #AES解密
        aes = AES.new('1122334455667788'.encode(), AES.MODE_CBC, '1122334455667788'.encode())
        decrypted_content = aes.decrypt(a2b_hex(content.encode('utf-8')))
        return (decrypted_content.decode('utf-8'))

    def get_mac(self):
        '''
        return the MAC address of the computer
        '''
        mac = None
        if sys.platform == "win32":  #區分系統類別
            for line in os.popen("ipconfig /all"):  # 運行命令行
                if line.strip().startswith("Physical Address") or line.strip().startswith("物理地址"):# 默認獲取第一個網卡mac地址
                    mac = line.split(":")[1].strip().replace("-", ":")
                    break
        else:#linux或者mac系統
            mac_address = uuid.UUID(int=uuid.getnode()).hex[-12:].upper()
            mac = ':'.join([mac_address[i:i + 2] for i in range(0, 11, 2)])
        print(mac)
        return mac





if __name__ == '__main__':
    mac = '00:FB:F1:B8:23:1A'              #主機mac地址
    deadline_use_time = '20220620'         #設置的過期時間
    pwd = '1122334455667788'               #16位字符祕鑰

    get_license_file(mac, deadline_use_time, pwd).gen_license_file()   #生成license
    # check_license_file().get_mac()           #檢測license

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章