#include "registration_api.h" #include "machine_code.h" #include "sha256.h" #include #include #include #include #include #include #include // 全局变量来存储机器码和密钥,避免重复计算 static std::string machineCode_cache; static std::string licenseKey_cache; static std::string expiration_date_str = "2099-12-31"; // 默认永久 // 内部函数,用于初始化缓存 void InitializeCache() { if (machineCode_cache.empty()) { machineCode_cache = getMachineCode(); } if (licenseKey_cache.empty()) { licenseKey_cache = picosha2::hash256_hex_string(machineCode_cache).substr(0, 32); // Truncate to 32 chars } } // --- Encryption/Decryption Helpers --- // Generates a key from the machine code for XOR operations std::string generate_xor_key(const std::string& machine_code) { return picosha2::hash256_hex_string(machine_code).substr(0, 32); } // XORs data with a key. Handles key repeating. std::string xor_string(const std::string& data, const std::string& key) { std::string output = data; for (size_t i = 0; i < data.size(); ++i) { output[i] = data[i] ^ key[i % key.length()]; } return output; } // Converts a string to its hex representation std::string string_to_hex(const std::string& in) { std::stringstream ss; ss << std::hex << std::setfill('0'); for (unsigned char c : in) { ss << std::setw(2) << static_cast(c); } return ss.str(); } // Converts a hex string back to a normal string std::string hex_to_string(const std::string& in) { std::string output; if (in.length() % 2 != 0) { return ""; // Invalid hex } for (size_t i = 0; i < in.length(); i += 2) { std::string byteString = in.substr(i, 2); char byte = (char)strtol(byteString.c_str(), NULL, 16); output.push_back(byte); } return output; } // C-style string return needs to be managed carefully. // We use static buffers here, which is not thread-safe but simple. // For a real-world app, consider returning std::string or managing memory better. static char machineCode_cstr[256]; static char licenseKey_cstr[256]; const char* GetMachineCode() { InitializeCache(); strncpy_s(machineCode_cstr, machineCode_cache.c_str(), sizeof(machineCode_cstr) - 1); machineCode_cstr[sizeof(machineCode_cstr) - 1] = '\0'; return machineCode_cstr; } const char* GetLicenseKey() { InitializeCache(); strncpy_s(licenseKey_cstr, licenseKey_cache.c_str(), sizeof(licenseKey_cstr) - 1); licenseKey_cstr[sizeof(licenseKey_cstr) - 1] = '\0'; return licenseKey_cstr; } int ValidateLicenseOffline(const char* key) { if (!key) { return 1; // 失败 } InitializeCache(); if (licenseKey_cache != key) { return 1; // 失败 } // 检查有效期 if (expiration_date_str != "2099-12-31") { std::tm tm = {}; std::stringstream ss(expiration_date_str); ss >> std::get_time(&tm, "%Y-%m-%d"); auto expiration_time = std::chrono::system_clock::from_time_t(std::mktime(&tm)); if (std::chrono::system_clock::now() > expiration_time) { return 2; // 过期 } } return 0; // 成功 } void SetOfflineExpiration(const char* expiration_date) { if (expiration_date) { expiration_date_str = expiration_date; } } int GenerateLicenseFile(const char* expiration_date) { if (!expiration_date) { return 1; // 失败 } InitializeCache(); std::string data_to_sign = machineCode_cache + expiration_date; std::string signature = picosha2::hash256_hex_string(data_to_sign); std::ofstream license_file("License.data"); if (!license_file.is_open()) { return 1; // 失败 } license_file << expiration_date << std::endl; license_file << signature << std::endl; license_file.close(); return 0; // 成功 } int GenerateLicenseFileFromCode(const char* machine_code, const char* expiration_date) { if (!machine_code || !expiration_date) { return 1; // 失败 } std::string mc_str(machine_code); std::string exp_str(expiration_date); // 1. Encrypt the expiration date std::string xor_key = generate_xor_key(mc_str); std::string encrypted_date = xor_string(exp_str, xor_key); std::string encrypted_date_hex = string_to_hex(encrypted_date); // 2. Create a signature of the machine code and the *encrypted* date std::string data_to_sign = mc_str + encrypted_date_hex; std::string signature = picosha2::hash256_hex_string(data_to_sign); // 3. Write the encrypted date and signature to the file std::ofstream license_file("License.data"); if (!license_file.is_open()) { return 1; // 失败 } license_file << encrypted_date_hex << std::endl; license_file << signature << std::endl; license_file.close(); return 0; // 成功 } int ValidateLicenseFile() { std::ifstream license_file("License.data"); if (!license_file.is_open()) { return 1; // 失败 - 文件不存在 } std::string file_encrypted_date_hex; std::string file_signature; std::getline(license_file, file_encrypted_date_hex); std::getline(license_file, file_signature); license_file.close(); if (file_encrypted_date_hex.empty() || file_signature.empty()) { return 1; // 失败 - 文件格式错误 } // 1. Verify the signature first to ensure integrity InitializeCache(); // Loads local machine code into machineCode_cache std::string data_to_verify = machineCode_cache + file_encrypted_date_hex; std::string expected_signature = picosha2::hash256_hex_string(data_to_verify); if (file_signature != expected_signature) { return 1; // 失败 - 签名不匹配, 文件被篡改或不属于此机器 } // 2. Decrypt the date std::string xor_key = generate_xor_key(machineCode_cache); std::string encrypted_date = hex_to_string(file_encrypted_date_hex); std::string decrypted_date = xor_string(encrypted_date, xor_key); // 3. Check the expiration date std::tm tm = {}; std::stringstream ss(decrypted_date); ss >> std::get_time(&tm, "%Y-%m-%d"); if (ss.fail()) { return 1; // 失败 - 日期格式损坏 } auto expiration_time = std::chrono::system_clock::from_time_t(std::mktime(&tm)); expiration_time += std::chrono::hours(23) + std::chrono::minutes(59) + std::chrono::seconds(59); if (std::chrono::system_clock::now() > expiration_time) { return 2; // 过期 } return 0; // 成功 }