From 7525b07d5bdd9d368c104c847afe5032c95aaec6 Mon Sep 17 00:00:00 2001 From: chengchongzhen <15939054361@163.com> Date: Mon, 30 Dec 2024 13:42:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E8=AE=B8=E5=8F=AF?= =?UTF-8?q?=E8=AF=81=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8AES-256-CBC=E5=8A=A0=E5=AF=86=E5=92=8C=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=EF=BC=8C=E5=A2=9E=E5=8A=A0=E7=94=9F=E6=88=90=E8=AE=B8?= =?UTF-8?q?=E5=8F=AF=E8=AF=81=E5=AF=86=E9=92=A5=E7=9A=84API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- license_manager.py | 44 +++++++++++++++++++++++++++++----- server/server.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/license_manager.py b/license_manager.py index 9a79f2f..7fc3020 100644 --- a/license_manager.py +++ b/license_manager.py @@ -5,7 +5,8 @@ import platform import uuid import hashlib from datetime import datetime -from cryptography.fernet import Fernet +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.backends import default_backend import base64 @@ -21,7 +22,38 @@ class LicenseManager: "https://your-activation-server.com/verify" # 替换为您的验证服务器地址 ) self.key = b"Kj8nP9x2Qs5mY7vR4wL1hC3fA6tD0iB8" - self.fernet = Fernet(base64.b64encode(self.key)) + + def encrypt(self, text): + """使用AES-256-CBC加密""" + cipher = Cipher( + algorithms.AES(self.key), + modes.CBC(self.key[:16]), + backend=default_backend(), + ) + encryptor = cipher.encryptor() + + # 添加PKCS7填充 + length = 16 - (len(text) % 16) + text += bytes([length]) * length + + encrypted = encryptor.update(text) + encryptor.finalize() + return base64.b64encode(encrypted).decode("utf-8") + + def decrypt(self, encrypted_text): + """使用AES-256-CBC解密""" + encrypted = base64.b64decode(encrypted_text) + cipher = Cipher( + algorithms.AES(self.key), + modes.CBC(self.key[:16]), + backend=default_backend(), + ) + decryptor = cipher.decryptor() + + decrypted = decryptor.update(encrypted) + decryptor.finalize() + + # 移除PKCS7填充 + padding_length = decrypted[-1] + return decrypted[:-padding_length] def get_hardware_info(self): """获取硬件信息作为机器码""" @@ -127,8 +159,8 @@ class LicenseManager: """加密保存许可证数据""" try: os.makedirs(os.path.dirname(self.license_file), exist_ok=True) - encrypted_data = self.fernet.encrypt(json.dumps(license_data).encode()) - with open(self.license_file, "wb") as f: + encrypted_data = self.encrypt(json.dumps(license_data).encode()) + with open(self.license_file, "w") as f: f.write(encrypted_data) except Exception as e: print(f"保存许可证出错: {e}") @@ -136,9 +168,9 @@ class LicenseManager: def _load_license(self): """加密读取许可证数据""" try: - with open(self.license_file, "rb") as f: + with open(self.license_file, "r") as f: encrypted_data = f.read() - decrypted_data = self.fernet.decrypt(encrypted_data) + decrypted_data = self.decrypt(encrypted_data) return json.loads(decrypted_data) except Exception as e: print(f"读取许可证出错: {e}") diff --git a/server/server.js b/server/server.js index db9bd8b..45cc099 100644 --- a/server/server.js +++ b/server/server.js @@ -12,11 +12,50 @@ const app = express(); app.use(cors()); app.use(express.json()); +// Encryption functions +function encryptLicenseKey(text) { + const cipher = crypto.createCipher('aes-256-cbc', process.env.ENCRYPTION_KEY); + let encrypted = cipher.update(text, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + return encrypted; +} + +function decryptLicenseKey(encrypted) { + const decipher = crypto.createDecipher('aes-256-cbc', process.env.ENCRYPTION_KEY); + let decrypted = decipher.update(encrypted, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} + +function generateLicenseKey() { + const randomBytes = crypto.randomBytes(16); + const timestamp = Date.now().toString(); + const combined = randomBytes.toString('hex') + timestamp; + return encryptLicenseKey(combined).substring(0, 32); // 生成32位的许可证密钥 +} + // Connect to MongoDB mongoose.connect(process.env.MONGODB_URI) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('MongoDB connection error:', err)); +// Generate license key endpoint +app.post('/generate', async (req, res) => { + try { + const licenseKey = generateLicenseKey(); + return res.json({ + success: true, + license_key: licenseKey + }); + } catch (error) { + console.error('生成许可证错误:', error); + return res.status(500).json({ + success: false, + message: '服务器错误' + }); + } +}); + // Activation endpoint app.post('/activate', async (req, res) => { try { @@ -30,6 +69,16 @@ app.post('/activate', async (req, res) => { }); } + // Validate license key format + try { + decryptLicenseKey(license_key); + } catch (error) { + return res.status(400).json({ + success: false, + message: '无效的许可证密钥' + }); + } + // Check if license already exists const existingLicense = await License.findOne({ licenseKey: license_key }); if (existingLicense) { @@ -90,6 +139,16 @@ app.post('/verify', async (req, res) => { }); } + // Validate license key format + try { + decryptLicenseKey(license_key); + } catch (error) { + return res.status(400).json({ + success: false, + message: '无效的许可证密钥' + }); + } + // Find license const license = await License.findOne({ licenseKey: license_key });