From 5e1e4a4b57e298806dba97175fa1fbd5c771c7cd Mon Sep 17 00:00:00 2001
From: ccy <3140717620@qq.com>
Date: 星期五, 09 十月 2026 16:17:18 +0800
Subject: [PATCH] 新的加密方式
---
licensedata.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 112 insertions(+), 0 deletions(-)
diff --git a/licensedata.cpp b/licensedata.cpp
index 26d5d1b..fa31615 100644
--- a/licensedata.cpp
+++ b/licensedata.cpp
@@ -1,5 +1,7 @@
锘�#include "licensedata.h"
#include <QDataStream>
+#include <QCryptographicHash>
+#include <QRandomGenerator>
#include <QtDebug>
LicenseData::LicenseData()
@@ -105,6 +107,116 @@
.arg(activeState);
}
+// ===== V3 绱у噾鏍煎紡锛�20浣嶈鍙瘑閽ョ敤锛�=====
+
+QByteArray LicenseData::machineFingerprint(const QByteArray &uuid, const QByteArray &cpu, const QByteArray &key)
+{
+ // 涓巘oBinary鐩稿悓鐨勫畾闀胯鏁达紝淇濊瘉鎺堟潈绔拰楠岃瘉绔鍚屼竴鍙版満鍣ㄧ畻鍑哄悓涓�鎸囩汗
+ QByteArray u = uuid.left(16);
+ u.append(QByteArray(16 - u.size(), '\0'));
+ QByteArray c = cpu.left(8);
+ c.append(QByteArray(8 - c.size(), '\0'));
+
+ QCryptographicHash hash(QCryptographicHash::Sha256);
+ hash.addData(key);
+ hash.addData(u);
+ hash.addData(c);
+ return hash.result().left(8);
+}
+
+quint16 LicenseData::crc16(const QByteArray &data)
+{
+ // CRC16-CCITT (0xFFFF 鍒濆�硷紝0x1021 澶氶」寮�)
+ quint16 crc = 0xFFFF;
+ for (int i = 0; i < data.size(); ++i) {
+ crc ^= static_cast<quint16>(static_cast<unsigned char>(data.at(i))) << 8;
+ for (int b = 0; b < 8; ++b) {
+ crc = (crc & 0x8000) ? static_cast<quint16>((crc << 1) ^ 0x1021)
+ : static_cast<quint16>(crc << 1);
+ }
+ }
+ return crc;
+}
+
+QByteArray LicenseData::toBinaryV3(const QByteArray &key) const
+{
+ QByteArray data(16, '\0');
+
+ // [0..7] 鏈哄櫒鎸囩汗
+ QByteArray fp = machineFingerprint(boardUuid, cpuSerial, key);
+ memcpy(data.data(), fp.constData(), 8);
+
+ // [8..9] 澶辨晥鏃ユ湡锛堜笌V2鍚屼竴2000-01-01鍩哄噯锛�
+ quint16 days = dateToDays(expireDate);
+ data[8] = static_cast<char>((days >> 8) & 0xFF);
+ data[9] = static_cast<char>(days & 0xFF);
+
+ // [10] 浜у搧鍙�
+ data[10] = static_cast<char>(productId);
+
+ // [11] 鐗堟湰锛氶珮4浣嶄富鐗堟湰 | 浣�4浣嶆鐗堟湰
+ data[11] = static_cast<char>(((verMajor & 0x0F) << 4) | (verMinor & 0x0F));
+
+ // [12] 鏍囧織锛氶珮4浣嶆牸寮忕増鏈�(1)锛屼綆4浣嶆縺娲荤姸鎬�
+ data[12] = static_cast<char>(0x10 | (activeState & 0x0F));
+
+ // [13..14] CRC16锛堣鐩朳0..12]锛岄殢鏈虹洂涓嶅弬涓庯級
+ quint16 crc = crc16(data.left(13));
+ data[13] = static_cast<char>((crc >> 8) & 0xFF);
+ data[14] = static_cast<char>(crc & 0xFF);
+
+ // [15] 闅忔満鐩�
+ data[15] = static_cast<char>(QRandomGenerator::global()->generate() & 0xFF);
+
+ return data;
+}
+
+bool LicenseData::fromBinaryV3(const QByteArray &data)
+{
+ if (data.size() != 16) {
+ return false;
+ }
+
+ quint8 flags = static_cast<quint8>(data.at(12));
+ if ((flags >> 4) != 0x01) {
+ qWarning() << "LicenseData::fromBinaryV3: not a V3 payload, format version ="
+ << (flags >> 4);
+ return false;
+ }
+
+ quint16 expectCrc = static_cast<quint16>((static_cast<quint8>(data.at(13)) << 8)
+ | static_cast<quint8>(data.at(14)));
+ if (crc16(data.left(13)) != expectCrc) {
+ qWarning() << "LicenseData::fromBinaryV3: CRC check failed, wrong key or corrupted data";
+ return false;
+ }
+
+ machineFp = data.left(8);
+
+ quint16 days = static_cast<quint16>((static_cast<quint8>(data.at(8)) << 8)
+ | static_cast<quint8>(data.at(9)));
+ expireDate = daysToDate(days);
+
+ productId = static_cast<quint8>(data.at(10));
+
+ quint8 ver = static_cast<quint8>(data.at(11));
+ verMajor = ver >> 4;
+ verMinor = ver & 0x0F;
+
+ activeState = flags & 0x0F;
+ return true;
+}
+
+QString LicenseData::toDebugStringV3() const
+{
+ return QString("{FP:%1, Expire:%2, Prod:%3, Ver:%4.%5, State:%6}")
+ .arg(binaryToHexString(machineFp))
+ .arg(expireDate.toString("yyyy-MM-dd"))
+ .arg(productId)
+ .arg(verMajor).arg(verMinor)
+ .arg(activeState);
+}
+
quint16 LicenseData::dateToDays(const QDate &date) const
{
QDate base(BASE_YEAR, BASE_MONTH, BASE_DAY);
--
Gitblit v1.9.1