diff --git a/client_decrypt.py b/client_decrypt.py new file mode 100644 index 0000000..29155e2 --- /dev/null +++ b/client_decrypt.py @@ -0,0 +1,73 @@ +from Crypto.Cipher import AES +import json +import binascii + + +class ResponseDecryptor: + def __init__(self, encryption_key): + """ + 初始化解密器 + :param encryption_key: 十六进制格式的密钥字符串 + """ + # 将十六进制字符串转换为字节 + self.key = binascii.unhexlify(encryption_key) + + def decrypt_response(self, encrypted_data): + """ + 解密服务器响应的数据 + :param encrypted_data: 加密的数据字符串 (格式: "iv:encrypted") + :return: 解密后的 JSON 数据 + """ + try: + # 分离 IV 和加密数据 + iv_hex, encrypted_text = encrypted_data.split(":") + + # 将十六进制转换为字节 + iv = binascii.unhexlify(iv_hex) + encrypted_bytes = binascii.unhexlify(encrypted_text) + + # 创建解密器 + cipher = AES.new(self.key, AES.MODE_CBC, iv) + + # 解密数据 + decrypted_bytes = cipher.decrypt(encrypted_bytes) + + # 移除填充 + padding_length = decrypted_bytes[-1] + decrypted_data = decrypted_bytes[:-padding_length] + + # 转换为字符串并解析 JSON + decrypted_str = decrypted_data.decode("utf-8") + return json.loads(decrypted_str) + + except Exception as e: + raise Exception(f"解密失败: {str(e)}") + + +# 使用示例 +def main(): + # 这里填入与服务器相同的加密密钥(十六进制格式) + ENCRYPTION_KEY = "f1e2d3c4b5a6978899aabbccddeeff00112233445566778899aabbccddeeff00" # 替换为实际的密钥 + + # 创建解密器实例 + decryptor = ResponseDecryptor(ENCRYPTION_KEY) + + # 模拟服务器响应 + server_response = { + "encrypted_data": "iv_hex:encrypted_data_hex" # 这里是服务器返回的加密数据 + } + + try: + # 解密数据 + decrypted_data = decryptor.decrypt_response(server_response["encrypted_data"]) + print("解密后的数据:", decrypted_data) + + # 现在可以访问解密后的数据 + if decrypted_data.get("success"): + print("操作成功!") + # 处理其他数据... + else: + print("操作失败:", decrypted_data.get("message")) + + except Exception as e: + print("错误:", str(e)) diff --git a/license_manager.py b/license_manager.py index babf9dc..4f3677b 100644 --- a/license_manager.py +++ b/license_manager.py @@ -9,6 +9,8 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import base64 import time +from Crypto.Cipher import AES +import binascii class LicenseManager: @@ -24,7 +26,11 @@ class LicenseManager: self.license_file = os.path.join(config_dir, "CursorPro", "license.json") self.activation_url = "http://119.8.35.41:3003/activate" self.verify_url = "http://119.8.35.41:3003/verify" + # 开发环境 + # self.activation_url = "http://127.0.0.1:3000/activate" + # self.verify_url = "http://127.0.0.1:3000/verify" self.key = b"Kj8nP9x2Qs5mY7vR4wL1hC3fA6tD0iB8" + self.encryption_key = b"f1e2d3c4b5a6978899aabbccddeeff00112233445566778899aabbccddeeff00" # 与服务器端相同的密钥 def encrypt(self, text): """使用AES-256-CBC加密""" @@ -96,20 +102,27 @@ class LicenseManager: ) if response.status_code == 200: - result = response.json() - if result.get("success"): - license_data = { - "license_key": license_key, - "machine_code": machine_code, - "activation_date": activation_data["activation_date"], - "expiry_date": result.get("expiry_date"), - "is_active": True, - } - self._save_license(license_data) - return True, "激活成功!" - else: - error_msg = result.get("message", "激活失败") - return False, error_msg + try: + encrypted_response = response.json() + result = self.decrypt_response( + encrypted_response["encrypted_data"] + ) + if result.get("success"): + license_data = { + "license_key": license_key, + "machine_code": machine_code, + "activation_date": activation_data["activation_date"], + "expiry_date": result.get("expiry_date"), + "is_active": True, + } + self._save_license(license_data) + return True, "激活成功!" + else: + error_msg = result.get("message", "激活失败") + return False, error_msg + except Exception as e: + return False, f"解密响应失败: {str(e)}" + else: return False, f"服务器响应错误: HTTP {response.status_code}" @@ -117,10 +130,39 @@ class LicenseManager: return False, "无法连接到激活服务器,请检查网络连接" except requests.exceptions.Timeout: return False, "服务器响应超时" + except Exception as e: + return False, f"激活请求失败: {str(e)}" except Exception as e: return False, f"激活过程出错: {str(e)}" + def decrypt_response(self, encrypted_data): + """解密服务器响应的数据""" + try: + # 分离 IV 和加密数据 + iv_hex, encrypted_text = encrypted_data.split(":") + + # 将十六进制转换为字节 + iv = binascii.unhexlify(iv_hex) + encrypted_bytes = binascii.unhexlify(encrypted_text) + + # 创建解密器 + cipher = AES.new(binascii.unhexlify(self.encryption_key), AES.MODE_CBC, iv) + + # 解密数据 + decrypted_bytes = cipher.decrypt(encrypted_bytes) + + # 移除填充 + padding_length = decrypted_bytes[-1] + decrypted_data = decrypted_bytes[:-padding_length] + + # 转换为字符串并解析 JSON + decrypted_str = decrypted_data.decode("utf-8") + return json.loads(decrypted_str) + + except Exception as e: + raise Exception(f"解密失败: {str(e)}") + def verify_license(self): """验证许可证""" try: @@ -142,18 +184,19 @@ class LicenseManager: try: response = requests.post(self.verify_url, json=verify_data, timeout=30) - time.sleep(2) - try: - result = response.json() - except Exception: - return False, "服务器响应格式错误" - if response.status_code == 200: - if result.get("success"): - return True, "许可证有效" - return False, result.get("message", "许可证无效") + try: + encrypted_response = response.json() + result = self.decrypt_response( + encrypted_response["encrypted_data"] + ) + if result.get("success"): + return True, "许可证有效" + return False, result.get("message", "许可证无效") + except Exception as e: + return False, f"解密响应失败: {str(e)}" return False, f"服务器响应错误: HTTP {response.status_code}" diff --git a/server/server.js b/server/server.js index 471b812..5bbfdd6 100644 --- a/server/server.js +++ b/server/server.js @@ -52,6 +52,21 @@ function generateLicenseKey() { return encrypted; } +// 在现有的加密函数下添加新的响应加密函数 +function encryptResponse(data) { + // 将对象转换为 JSON 字符串 + const jsonStr = JSON.stringify(data); + const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex'); + const iv = getIV(); + const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); + let encrypted = cipher.update(jsonStr, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + // 将 IV 附加到加密文本中 + return { + encrypted_data: iv.toString('hex') + ':' + encrypted + }; +} + // Connect to MongoDB mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, @@ -86,22 +101,24 @@ app.post(`/${GENERATE_PATH}`, async (req, res) => { try { const licenseKey = generateLicenseKey(); - // 保存生成的许可证记录 await LicenseKey.create({ licenseKey: licenseKey, isUsed: false }); - return res.json({ + // 加密响应数据 + const responseData = { success: true, license_key: licenseKey - }); + }; + + return res.json(responseData); } catch (error) { console.error('生成许可证错误:', error); - return res.status(500).json({ + return res.status(500).json(encryptResponse({ success: false, message: '服务器错误' - }); + })); } }); @@ -164,7 +181,7 @@ app.post('/activate', async (req, res) => { expiryDate: expiryDate, isActive: true, maxUsageCount: process.env.MAX_USAGE_COUNT || 10, - currentUsageCount: 0 + currentUsageCount: 1 }]); @@ -172,17 +189,19 @@ app.post('/activate', async (req, res) => { licenseKeyRecord.isUsed = true; await licenseKeyRecord.save(); - return res.json({ + const responseData = { success: true, message: '激活成功', expiry_date: expiryDate - }); + }; + + return res.json(encryptResponse(responseData)); } catch (error) { console.error('激活错误:', error); - return res.status(500).json({ + return res.status(500).json(encryptResponse({ success: false, message: '服务器错误' - }); + })); } }); @@ -255,7 +274,7 @@ app.post('/verify', async (req, res) => { license.currentUsageCount += 1; await license.save(); - return res.json({ + const responseData = { success: true, message: '许可证有效', expiry_date: formatChinaTime(license.expiryDate, 'YYYY-MM-DD'), @@ -263,13 +282,15 @@ app.post('/verify', async (req, res) => { current: license.currentUsageCount, max: license.maxUsageCount } - }); + }; + + return res.json(encryptResponse(responseData)); } catch (error) { console.error('验证错误:', error); - return res.status(500).json({ + return res.status(500).json(encryptResponse({ success: false, message: '服务器错误' - }); + })); } });