开发完一个产品要通过加密解密来保护产品权益和控制运行,其中核心环节是读取电脑硬件信息和加密解密算法。这里介绍一种常用的方法。
# encoding = utf-8
# Time : 2023/09/16 18:36
# S.py 读取电脑产品码
# Author : HiFine
import wmi
import base64
from pyDes import *
import time
import registerGUI #导入注册界面
from tkinter import *
from tkinter.messagebox import *
rgGUI = None
yxtime = "" #有效期
Des_key = " Key,需八位"
Des_IV = "自定IV向量x112x2a31x272"
Date_Time = "2026-09-26 00:00:00" #定义截止日期
# 获取硬件信息,输出macode
# 1、CPU序列号(ID) 2、本地连接 无线局域网 以太网的MAC 3.硬盘序列号(唯一) 4.主板序列号(唯一)
global s
s = wmi.WMI()
# cpu序列号
def get_CPU_info():
cpu = []
cp = s.Win32_Processor()
for u in cp:
cpu.append(
{
"Name": u.Name,
"Serial Number": u.ProcessorId,
"CoreNum": u.NumberOfCores
}
)
return cpu
# 硬盘序列号
def get_disk_info():
disk = []
for pd in s.Win32_DiskDrive():
disk.append(
{
"Serial": s.Win32_PhysicalMedia()[0].SerialNumber.lstrip().rstrip(), # 获取硬盘序列号
"ID": pd.deviceid,
"Caption": pd.Caption,
"size": str(int(float(pd.Size) / 1024 / 1024 / 1024))
}
)
return disk
# mac地址(包括虚拟机)
def get_network_info():
network = []
for nw in s.Win32_NetworkAdapterConfiguration():
if nw.MacAddress != None:
network.append(
{
"MAC": nw.MacAddress,
"ip": nw.IPAddress
}
)
return network
# 主板序列号
def get_mainboard_info():
mainboard = []
for board_id in s.Win32_BaseBoard():
mainboard.append(board_id.SerialNumber.strip().strip('.'))
return mainboard
# 由于机器码矿太长,故选取机器码字符串部分字符(此处获得机器码用于传给管理员)
def getCombinNumber():
#a =get_network_info()
b = get_CPU_info()
c = get_disk_info()
d = get_mainboard_info()
# print('网卡:',a)
# print('处理器:',b)
# print('硬盘:',c)
# print('主板:',d)
machinecode_str = ""
machinecod服务器托管网e_str = machinecode_str + b[0]['Serial Number'] + c[0]['Serial'] + d[0]
#machinecode_str = machinecode_str + a[0]['MAC'] + b[0]['Serial Number'] + c[0]['Serial'] + d[0]
#print('机器码数据:',machinecode_str)
#selectIndex = [8, 10, 15, 16, 17, 30, 32, 38, 43, 46]
selectIndex = [随机正整数]
macode = ""
for i in selectIndex:
macode = macode + machinecode_str[i]
#print(machinecode_str[i])
return macode
#合并得到授权码(包含机器码和日期)
def get_ComMacdate():
macDateCode = getCombinNumber() + Date_Time
return macDateCode
# DES+base64加密机器码+授权时间
def Encryted(tr):
k = des(Des_key, CBC, Des_IV, pad=None, padmode=PAD_PKCS5)
EncryptStr = k.encrypt(tr)
return base64.b32encode(EncryptStr) # 转base64编码返回
# base64+DES解密机器码+授权时间
def Dncryted(EncryptStr):
bas1 = base64.b32decode(EncryptStr) #先对加密后的对象解密
k = des(Des_key, CBC, Des_IV, pad=None, padmode=PAD_PKCS5)
tr = k.decrypt(bas1)
return tr
#从加密后的授权码中将日期解析出来(传入字符串即可,里面自动转换成bytes类型,好用于解码)
def jiexi_datetime(jiami_macDateCode):
#对从注册文件中的进行还原成bytes类型
jiami_macDateCode = bytes(jiami_macDateCode, encoding='utf-8')
#print(jiami_macDateCode)
#将解密得到机器码+日期
try:
jiemi_macDateCode = Dncryted(jiami_macDateCode)
except:
return None
#print('jiemi_macDateCode',jiemi_macDateCode)
jiemi_macDateCode = str(jiemi_macDateCode).replace("b'", '').replace("'", '') # 将授权码变成字符串
maccode = getCombinNumber() #获得本机的机器码
maccode = str(maccode).replace("b'",'').replace("'",'') #将机器码变成字符串
#print('本机机器码',maccode) :001B6AXH8
#如果本机机器码在授权码中
if maccode in jiemi_macDateCode:
Datetime = jiemi_macDateCode.replace(maccode,'') #将机器码替换就得到日期了
else:
return None
return Datetime #2023-09-16 00:00:00
#判断当前日期是否大于有效截服务器托管网止期
def check_time(Datetime):
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if nowtime > Datetime:
#print("已过期,无法正常使用")
return False
else:
#print("未过期,可正常使用")
return True
# 用于检查验证注册信息的唯一及有效日期
def checkAuthor():
global rgGUI
global yxtime
try:
with open('./DATA/register.txt', 'r') as f:
key = f.read() #读取所有信息
except:
return False
key = key.strip() # 去除换行符的影响
#print(key)
#print(type(key))
datetime =jiexi_datetime(key) #对key的内容解析,解析成功不是None,说明是本机唯一验证码
if datetime==None:
# 隐藏以tk开头的弹窗
root = Tk()
root.withdraw()
root.iconbitmap('./images/tb02.ico')
#弹出提示信息
messagebox.showinfo(title='提示',message='请输入正确的注册码完成注册')#注册码错误请重新输入
#print("非本机注册码,无效")
return False
else:
if check_time(datetime):
yxtime = datetime #获得截止日期
return True
else:
# 隐藏以tk开头的弹窗
root = Tk()
root.withdraw()
root.iconbitmap('./images/tb02.ico')
#弹出提示信息
messagebox.showinfo(title='提示',message='注册码已过期!')
#print("已过期,无法使用")
return False
#用于点击按钮进行注册(即保存注册信息)
def regis():
global rgGUI
global yxtime
key = rgGUI.message.get('0.0','end') #获取text中的全部内容
#print(key)
# 读写文件要加判断(将内容写入注册文件中)
with open('./DATA/register.txt', 'w') as f:
f.write(key)
#注册信息后立即进行验证
if checkAuthor():
rgGUI.root.destroy() #销毁窗口并进入下一环节
# 进入主界面
maingui = mainGUI.mainGUI()
maingui.yxqL['text'] = "有效期截止到:"+yxtime + "n" + "n" +"请关闭页面重新登陆"
maingui.root.mainloop()
else:
#验证失败返回到注册界面
return
#该函数用来将需要的字符串或文字复制到剪切板.
def Copy_To_Clipboard(string):
from tkinter import Tk
r = Tk()
r.withdraw()
r.clipboard_clear()
r.clipboard_append(string)
r.update()
# 粘贴事件函数(将粘贴板上的信息粘贴入文本框(message))
def callback(event=None):
rgGUI.message.event_generate('>')
#显示注册窗口
def show_reg():
ma1 = getCombinNumber() # 获得本机机器码,并将其显示在界面上:001B6AXH8
global rgGUI
rgGUI = registerGUI.registerMGUI(version="1.2") # 创建界面窗口对象(包含窗口及其各个控件)
#rgGUI.button_start.bind("", lambda x: regis()) # 点击注册
rgGUI.button_copy1.bind("", lambda x: Copy_To_Clipboard(ma1)) #复制产品码到粘贴板
#rgGUI.button_paste.bind("", callback) #将粘贴板上的信息粘贴到文本框
rgGUI.alert(ma1) # 将机器码显示在窗口界面
#print(ma1)
#rgGUI.root.attributes("-topmost", True)
# 手动加入消息队列
rgGUI.root.mainloop()
if __name__ == '__main__':
show_reg()
运行测试结果如下:
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
RP2040是一种基于ARM Cortex-M0+核心的微控制器芯片,由Raspberry Pi公司设计和生产。它主要用于树莓派计算模块和树莓派相机模块服务器托管网V2等产品中,同时也适用于各种低功耗物联网设备和其他嵌入式应用。 RP2040具有高度集成和低功…