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