原理
本地计算机生成机器码并发送给服务器,服务器随机生成一段字符串并存储到数据库里,验证时通过服务器进行查询
使用到的库/工具
库
- wmi
- hashlib
- requests
- os
- flask
- random
- sqlite3
工具
- Postman
- Navicat for SQLite
代码
数据库表结构
表:data
客户端
import wmi
import hashlib
import requests
import os
s = wmi.WMI()
# CPU序列号
def get_CPU_info():
cpu = []
cp = s.Win32_Processor()
for u in cp:
cpu.append(u.ProcessorId)
return "".join(cpu)
# 硬盘序列号
def get_disk_info():
disk = []
for pd in s.Win32_DiskDrive():
disk.append(s.Win32_PhysicalMedia()[0].SerialNumber.lstrip().rstrip() + pd.deviceid)
return "".join(disk)
# 主板序列号
def get_mainboard_info():
mainboard = []
for board_id in s.Win32_BaseBoard():
mainboard.append(board_id.SerialNumber.strip().strip('.'))
return "".join(mainboard)
key_org = get_CPU_info() + get_disk_info() + get_mainboard_info() # 将所有序列号拼接在一起
md5 = hashlib.md5(key_org.encode()).hexdigest()[:16].upper() # 进行MD5加密,16是截取的长度,可根据需要自行更改
def main(): # 这里是运行的主程序
print("进入主程序")
def inputKey(): # 激活码输入
key = input("请输入激活码:")
result = requests.post(URL + "/verify?machineID=%s&key=%s" % (md5, key)).json()['result']
if result == "success":
f = open("register.bin", "w")
f.write(key)
f.close()
print("激活成功")
main()
else:
print("激活码错误")
inputKey()
URL = "http://127.0.0.1:5000" # 激活服务器
requests.post(URL + "/generator?machineID=%s" % md5) # 未生成激活码的机器先生成激活码
if os.path.exists("register.bin"): # 检测是否存在激活文件
f = open("register.bin", "r").read()
result = requests.post(URL + "/verify?machineID=%s&key=%s" % (md5, f)).json()['result'] # 校验激活文件是否正常
if result == "success":
print("已激活")
main()
else:
print("激活码异常")
os.remove("register.bin") # 移除激活文件
inputKey() # 重新询问激活码
else:
inputKey() # 询问激活码
注:在main()函数中添加主程序
服务端
import flask
from flask import *
import hashlib
import random
import sqlite3
app = flask.Flask(__name__)
DATABASE_FILE = "data.db" # 数据库文件,可根据需要自行更改
@app.route("/generator", methods = ["POST"]) # 激活码生成
def gen():
machineID = request.args.get('machineID')
conn = sqlite3.connect(database = DATABASE_FILE) # 连接数据库
cursor = conn.cursor()
sql = "SELECT machineID FROM data WHERE machineID = '%s'" % machineID # 查找机器是否已经生成激活码
cursor.execute(sql)
num = 0
for data in cursor.fetchall():
num += 1
if (num != 0):
conn.commit()
cursor.close()
conn.close()
return jsonify({"result": "failed"}) # 已经生成返回[失败]
else:
# 未生成进行生成
rint = random.randint(100000000000000, 999999999999999) # 选取随机数
md5 = hashlib.md5(str(rint).encode()).hexdigest()[:16].upper() # 进行MD5加密,16是截取的长度,可根据需要自行更改
sql = "INSERT INTO data(machineID,key) VALUES('%s', '%s')" % (machineID, md5)
cursor.execute(sql)
conn.commit()
cursor.close()
conn.close()
return jsonify({"result": "success"}) # 返回[成功]
@app.route("/verify", methods = ["POST"]) # 激活码验证
def verify():
machineID = request.args.get('machineID')
key = request.args.get('key')
conn = sqlite3.connect(database = DATABASE_FILE) # 连接数据库
cursor = conn.cursor()
sql = "SELECT machineID,key FROM data WHERE machineID = '%s' and key = '%s'" % (machineID, key) # 查询激活码是否正确
cursor.execute(sql)
num = 0
for data in cursor.fetchall():
num += 1
if (num != 0):
return jsonify({"result": "success"}) # 成功
else:
return jsonify({"result": "failed"}) # 错误
conn.commit()
cursor.close()
conn.close()
app.run()