modify machine code get and enntry
This commit is contained in:
parent
cc9a5747f1
commit
0e7f56cf7c
@ -43,6 +43,10 @@ target_link_libraries(validate_only PRIVATE RegistrationDLL)
|
|||||||
add_executable(generate_valid src/generate_valid.cpp)
|
add_executable(generate_valid src/generate_valid.cpp)
|
||||||
target_link_libraries(generate_valid PRIVATE RegistrationDLL)
|
target_link_libraries(generate_valid PRIVATE RegistrationDLL)
|
||||||
|
|
||||||
|
# --- 生成有效许可证文件程序 ---
|
||||||
|
add_executable(generate_valid src/generate_valid.cpp)
|
||||||
|
target_link_libraries(generate_valid PRIVATE RegistrationDLL)
|
||||||
|
|
||||||
# 将生成的文件输出到 build/bin 目录
|
# 将生成的文件输出到 build/bin 目录
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|||||||
@ -12,35 +12,34 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
// 获取原始机器码
|
// --- Core Functions ---
|
||||||
|
|
||||||
|
// Gets the raw machine code.
|
||||||
REGISTRATION_API const char* GetMachineCode();
|
REGISTRATION_API const char* GetMachineCode();
|
||||||
|
|
||||||
// 获取加密后的许可证密钥
|
// Validates the license file.
|
||||||
REGISTRATION_API const char* GetLicenseKey();
|
// @return: 0=success, 1=failure, 2=expired.
|
||||||
|
REGISTRATION_API int ValidateLicenseFile();
|
||||||
|
|
||||||
// 验证许可证密钥 (离线)
|
// Generates a license file from a provided machine code.
|
||||||
// @param key: 要验证的密钥
|
// @param machine_code: The machine code to use.
|
||||||
// @return: 0=成功, 1=失败, 2=过期
|
// @param expiration_date: A date string in "YYYY-MM-DD" format.
|
||||||
REGISTRATION_API int ValidateLicenseOffline(const char* key);
|
// @return: 0=success, 1=failure.
|
||||||
|
|
||||||
// 设置离线许可证的有效期
|
|
||||||
// @param expiration_date: "YYYY-MM-DD" 格式的日期字符串
|
|
||||||
REGISTRATION_API void SetOfflineExpiration(const char* expiration_date);
|
|
||||||
|
|
||||||
// 生成许可证文件
|
|
||||||
// @param expiration_date: "YYYY-MM-DD" 格式的日期字符串
|
|
||||||
// @return: 0=成功, 1=失败
|
|
||||||
REGISTRATION_API int GenerateLicenseFile(const char* expiration_date);
|
|
||||||
|
|
||||||
// 从提供的机器码生成许可证文件
|
|
||||||
// @param machine_code: 要使用的机器码
|
|
||||||
// @param expiration_date: "YYYY-MM-DD" 格式的日期字符串
|
|
||||||
// @return: 0=成功, 1=失败
|
|
||||||
REGISTRATION_API int GenerateLicenseFileFromCode(const char* machine_code, const char* expiration_date);
|
REGISTRATION_API int GenerateLicenseFileFromCode(const char* machine_code, const char* expiration_date);
|
||||||
|
|
||||||
// 验证许可证文件
|
// --- New Encryption/Decryption API ---
|
||||||
// @return: 0=成功, 1=失败, 2=过期
|
|
||||||
REGISTRATION_API int ValidateLicenseFile();
|
// Generates a dynamic, 32-character encrypted code from the machine code.
|
||||||
|
// The returned string is managed by the DLL and should not be freed by the caller.
|
||||||
|
REGISTRATION_API const char* GenerateEncryptedCode();
|
||||||
|
|
||||||
|
// Decrypts a 32-character code to get the original machine code.
|
||||||
|
// @param encrypted_code: The 32-character hex string to decrypt.
|
||||||
|
// @param decrypted_machine_code: A buffer to store the null-terminated result.
|
||||||
|
// @param buffer_size: The size of the provided buffer.
|
||||||
|
// @return: 0 on success, 1 on failure (e.g., invalid format, bad length).
|
||||||
|
REGISTRATION_API int DecryptCodeAndGetMachineCode(const char* encrypted_code, char* decrypted_machine_code, int buffer_size);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "registration_api.h"
|
#include "registration_api.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <random>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "sha256.h"
|
|
||||||
|
|
||||||
// 简单的MD5实现(只返回32位)
|
|
||||||
std::string simple_md5_32(const std::string& input) {
|
|
||||||
// 使用SHA256但只取前32位,模拟MD5的32位输出
|
|
||||||
std::string full_hash = picosha2::hash256_hex_string(input);
|
|
||||||
return full_hash.substr(0, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IDC_MACHINE_CODE_LABEL 201
|
#define IDC_MACHINE_CODE_LABEL 201
|
||||||
#define IDC_MACHINE_CODE_EDIT 202
|
#define IDC_MACHINE_CODE_EDIT 202
|
||||||
@ -22,9 +10,7 @@ std::string simple_md5_32(const std::string& input) {
|
|||||||
LRESULT CALLBACK GenWndProc(HWND, UINT, WPARAM, LPARAM);
|
LRESULT CALLBACK GenWndProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
void CopyToClipboard(HWND hwnd, const std::string& text) {
|
void CopyToClipboard(HWND hwnd, const std::string& text) {
|
||||||
if (!OpenClipboard(hwnd)) {
|
if (!OpenClipboard(hwnd)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, text.size() + 1);
|
HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, text.size() + 1);
|
||||||
if (!hg) {
|
if (!hg) {
|
||||||
@ -79,55 +65,31 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
TranslateMessage(&Msg);
|
TranslateMessage(&Msg);
|
||||||
DispatchMessage(&Msg);
|
DispatchMessage(&Msg);
|
||||||
}
|
}
|
||||||
return Msg.wParam;
|
return (int)Msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK GenWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
LRESULT CALLBACK GenWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
static HWND hMachineCodeEdit;
|
static HWND hMachineCodeEdit;
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case WM_CREATE: {
|
case WM_CREATE: {
|
||||||
// Labels
|
CreateWindow("STATIC", "Your Encrypted Code:", WS_VISIBLE | WS_CHILD, 20, 20, 150, 20, hwnd, (HMENU)IDC_MACHINE_CODE_LABEL, NULL, NULL);
|
||||||
CreateWindow("STATIC", "Your Machine Code:", WS_VISIBLE | WS_CHILD, 20, 20, 150, 20, hwnd, (HMENU)IDC_MACHINE_CODE_LABEL, NULL, NULL);
|
hMachineCodeEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY | ES_CENTER, 180, 20, 280, 20, hwnd, (HMENU)IDC_MACHINE_CODE_EDIT, NULL, NULL);
|
||||||
|
CreateWindow("BUTTON", "Copy", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 470, 20, 50, 22, hwnd, (HMENU)IDC_COPY_BUTTON, NULL, NULL);
|
||||||
|
|
||||||
// Edit Controls
|
// --- Refactored Logic ---
|
||||||
hMachineCodeEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY | ES_CENTER, 180, 20, 330, 20, hwnd, (HMENU)IDC_MACHINE_CODE_EDIT, NULL, NULL);
|
// Call the new API function to get the encrypted code
|
||||||
|
const char* final_code = GenerateEncryptedCode();
|
||||||
// Buttons
|
SetWindowText(hMachineCodeEdit, final_code);
|
||||||
CreateWindow("BUTTON", "Copy to Clipboard", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 180, 60, 150, 30, hwnd, (HMENU)IDC_COPY_BUTTON, NULL, NULL);
|
|
||||||
|
|
||||||
// Set machine code with encryption
|
|
||||||
std::string machineCode = GetMachineCode();
|
|
||||||
|
|
||||||
// 1. 生成一个个位的随机数 (0-9)
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 gen(rd());
|
|
||||||
std::uniform_int_distribution<> dis(0, 9);
|
|
||||||
int randomNum = dis(gen);
|
|
||||||
|
|
||||||
// 2. 做一次 32位 MD5 加密 加密后是32位
|
|
||||||
std::string encryptedCode = simple_md5_32(machineCode);
|
|
||||||
|
|
||||||
// 3. 把 encryptedCode 字符串减掉这个数
|
|
||||||
std::string processedCode = encryptedCode;
|
|
||||||
for (char& c : processedCode) {
|
|
||||||
c = c - randomNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 把这个数变成一个字符插入到第三位的位置 加密后是33位
|
|
||||||
char randomChar = '0' + randomNum;
|
|
||||||
processedCode.insert(2, 1, randomChar);
|
|
||||||
|
|
||||||
SetWindowText(hMachineCodeEdit, processedCode.c_str());
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_COMMAND: {
|
case WM_COMMAND: {
|
||||||
switch (LOWORD(wParam)) {
|
switch (LOWORD(wParam)) {
|
||||||
case IDC_COPY_BUTTON: {
|
case IDC_COPY_BUTTON: {
|
||||||
char formattedMachineCode[256];
|
char codeToCopy[64];
|
||||||
GetWindowText(hMachineCodeEdit, formattedMachineCode, 256);
|
GetWindowText(hMachineCodeEdit, codeToCopy, sizeof(codeToCopy));
|
||||||
CopyToClipboard(hwnd, formattedMachineCode);
|
CopyToClipboard(hwnd, codeToCopy);
|
||||||
MessageBox(hwnd, "Machine code copied to clipboard!", "Success", MB_OK);
|
MessageBox(hwnd, "Encrypted code copied to clipboard!", "Success", MB_OK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,4 +105,4 @@ LRESULT CALLBACK GenWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
97
src/gui.cpp
97
src/gui.cpp
@ -1,20 +1,33 @@
|
|||||||
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "registration_api.h"
|
#include "registration_api.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
|
// --- Control IDs ---
|
||||||
#define IDC_STATUS_LABEL 101
|
#define IDC_STATUS_LABEL 101
|
||||||
#define IDC_MACHINE_CODE_LABEL 102
|
#define IDC_GEN_GROUP 102
|
||||||
#define IDC_MACHINE_CODE_EDIT 103
|
#define IDC_GEN_MC_LABEL 103
|
||||||
#define IDC_EXPIRATION_LABEL 104
|
#define IDC_GEN_MC_EDIT 104
|
||||||
#define IDC_EXPIRATION_EDIT 105
|
#define IDC_GEN_EXP_LABEL 105
|
||||||
#define IDC_GENERATE_BUTTON 106
|
#define IDC_GEN_EXP_EDIT 106
|
||||||
|
#define IDC_GEN_BUTTON 107
|
||||||
|
|
||||||
|
#define IDC_DEC_GROUP 201
|
||||||
|
#define IDC_DEC_INPUT_LABEL 202
|
||||||
|
#define IDC_DEC_INPUT_EDIT 203
|
||||||
|
#define IDC_DEC_BUTTON 204
|
||||||
|
#define IDC_DEC_OUTPUT_LABEL 205
|
||||||
|
#define IDC_DEC_OUTPUT_EDIT 206
|
||||||
|
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
static HWND hMachineCodeEdit, hExpirationEdit, hStatusLabel;
|
// --- Global Handles for UI Controls ---
|
||||||
|
static HWND hStatusLabel;
|
||||||
|
static HWND hGenMachineCodeEdit, hGenExpirationEdit;
|
||||||
|
static HWND hDecInputEdit, hDecOutputEdit;
|
||||||
|
|
||||||
|
// --- Function to update the license status label ---
|
||||||
void UpdateValidationStatus(HWND hwnd) {
|
void UpdateValidationStatus(HWND hwnd) {
|
||||||
int result = ValidateLicenseFile();
|
int result = ValidateLicenseFile();
|
||||||
std::string statusText;
|
std::string statusText;
|
||||||
@ -32,6 +45,7 @@ void UpdateValidationStatus(HWND hwnd) {
|
|||||||
SetWindowText(hStatusLabel, statusText.c_str());
|
SetWindowText(hStatusLabel, statusText.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Main Entry Point ---
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||||
WNDCLASSEX wc = {0};
|
WNDCLASSEX wc = {0};
|
||||||
wc.cbSize = sizeof(WNDCLASSEX);
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
@ -55,9 +69,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
HWND hwnd = CreateWindowEx(
|
HWND hwnd = CreateWindowEx(
|
||||||
WS_EX_CLIENTEDGE,
|
WS_EX_CLIENTEDGE,
|
||||||
"RegistrationWindowClass",
|
"RegistrationWindowClass",
|
||||||
"Software Registration",
|
"Software Registration Tool",
|
||||||
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX),
|
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX),
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, 480, 250,
|
CW_USEDEFAULT, CW_USEDEFAULT, 500, 400, // Increased window height
|
||||||
NULL, NULL, hInstance, NULL);
|
NULL, NULL, hInstance, NULL);
|
||||||
|
|
||||||
if (hwnd == NULL) {
|
if (hwnd == NULL) {
|
||||||
@ -73,52 +87,79 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||||||
TranslateMessage(&Msg);
|
TranslateMessage(&Msg);
|
||||||
DispatchMessage(&Msg);
|
DispatchMessage(&Msg);
|
||||||
}
|
}
|
||||||
return Msg.wParam;
|
return (int)Msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Window Procedure to Handle Messages ---
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case WM_CREATE: {
|
case WM_CREATE: {
|
||||||
// --- Top Part: Validation Status ---
|
// --- Top Part: Validation Status ---
|
||||||
hStatusLabel = CreateWindow("STATIC", "Checking license...", WS_VISIBLE | WS_CHILD | SS_CENTER, 20, 20, 420, 20, hwnd, (HMENU)IDC_STATUS_LABEL, NULL, NULL);
|
hStatusLabel = CreateWindow("STATIC", "Checking license...", WS_VISIBLE | WS_CHILD | SS_CENTER, 20, 15, 440, 20, hwnd, (HMENU)IDC_STATUS_LABEL, NULL, NULL);
|
||||||
UpdateValidationStatus(hwnd);
|
UpdateValidationStatus(hwnd);
|
||||||
|
|
||||||
|
// --- Middle Part: Decryption ---
|
||||||
|
CreateWindow("STATIC", "Decrypt Encrypted Code", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 10, 50, 460, 120, hwnd, (HMENU)IDC_DEC_GROUP, NULL, NULL);
|
||||||
|
CreateWindow("STATIC", "Encrypted Code:", WS_VISIBLE | WS_CHILD, 30, 80, 150, 20, hwnd, (HMENU)IDC_DEC_INPUT_LABEL, NULL, NULL);
|
||||||
|
hDecInputEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 190, 80, 260, 20, hwnd, (HMENU)IDC_DEC_INPUT_EDIT, NULL, NULL);
|
||||||
|
CreateWindow("BUTTON", "Decrypt", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 190, 110, 120, 30, hwnd, (HMENU)IDC_DEC_BUTTON, NULL, NULL);
|
||||||
|
CreateWindow("STATIC", "Original Machine Code:", WS_VISIBLE | WS_CHILD, 30, 145, 150, 20, hwnd, (HMENU)IDC_DEC_OUTPUT_LABEL, NULL, NULL);
|
||||||
|
hDecOutputEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_READONLY, 190, 145, 260, 20, hwnd, (HMENU)IDC_DEC_OUTPUT_EDIT, NULL, NULL);
|
||||||
|
|
||||||
// --- Bottom Part: License Generation ---
|
// --- Bottom Part: License Generation ---
|
||||||
CreateWindow("STATIC", "--- License Generation ---", WS_VISIBLE | WS_CHILD | SS_CENTER, 20, 60, 420, 20, hwnd, NULL, NULL, NULL);
|
CreateWindow("STATIC", "Generate License File", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 10, 180, 460, 160, hwnd, (HMENU)IDC_GEN_GROUP, NULL, NULL);
|
||||||
CreateWindow("STATIC", "Machine Code:", WS_VISIBLE | WS_CHILD, 20, 90, 150, 20, hwnd, (HMENU)IDC_MACHINE_CODE_LABEL, NULL, NULL);
|
CreateWindow("STATIC", "Machine Code:", WS_VISIBLE | WS_CHILD, 30, 210, 150, 20, hwnd, (HMENU)IDC_GEN_MC_LABEL, NULL, NULL);
|
||||||
hMachineCodeEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 180, 90, 260, 20, hwnd, (HMENU)IDC_MACHINE_CODE_EDIT, NULL, NULL);
|
hGenMachineCodeEdit = CreateWindow("EDIT", "", WS_VISIBLE | WS_CHILD | WS_BORDER, 190, 210, 260, 20, hwnd, (HMENU)IDC_GEN_MC_EDIT, NULL, NULL);
|
||||||
|
CreateWindow("STATIC", "Expiration (YYYY-MM-DD):", WS_VISIBLE | WS_CHILD, 30, 240, 150, 20, hwnd, (HMENU)IDC_GEN_EXP_LABEL, NULL, NULL);
|
||||||
CreateWindow("STATIC", "Expiration (YYYY-MM-DD):", WS_VISIBLE | WS_CHILD, 20, 120, 150, 20, hwnd, (HMENU)IDC_EXPIRATION_LABEL, NULL, NULL);
|
hGenExpirationEdit = CreateWindow("EDIT", "2099-12-31", WS_VISIBLE | WS_CHILD | WS_BORDER, 190, 240, 120, 20, hwnd, (HMENU)IDC_GEN_EXP_EDIT, NULL, NULL);
|
||||||
hExpirationEdit = CreateWindow("EDIT", "2099-12-31", WS_VISIBLE | WS_CHILD | WS_BORDER, 180, 120, 120, 20, hwnd, (HMENU)IDC_EXPIRATION_EDIT, NULL, NULL);
|
CreateWindow("BUTTON", "Generate License File", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 190, 280, 180, 30, hwnd, (HMENU)IDC_GEN_BUTTON, NULL, NULL);
|
||||||
|
|
||||||
CreateWindow("BUTTON", "Generate License File", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 180, 160, 180, 30, hwnd, (HMENU)IDC_GENERATE_BUTTON, NULL, NULL);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_COMMAND: {
|
case WM_COMMAND: {
|
||||||
switch (LOWORD(wParam)) {
|
switch (LOWORD(wParam)) {
|
||||||
case IDC_GENERATE_BUTTON: {
|
case IDC_GEN_BUTTON: {
|
||||||
char machineCode[256];
|
char machineCode[256];
|
||||||
char expirationDate[11];
|
char expirationDate[12];
|
||||||
GetWindowText(hMachineCodeEdit, machineCode, 256);
|
GetWindowText(hGenMachineCodeEdit, machineCode, sizeof(machineCode));
|
||||||
GetWindowText(hExpirationEdit, expirationDate, 11);
|
GetWindowText(hGenExpirationEdit, expirationDate, sizeof(expirationDate));
|
||||||
|
|
||||||
if (strlen(machineCode) == 0) {
|
if (strlen(machineCode) == 0) {
|
||||||
MessageBox(hwnd, "Please enter a machine code.", "Error", MB_ICONERROR);
|
MessageBox(hwnd, "Please enter a machine code for generation.", "Error", MB_ICONERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We are now using the function that takes the machine code as an argument
|
|
||||||
int result = GenerateLicenseFileFromCode(machineCode, expirationDate);
|
int result = GenerateLicenseFileFromCode(machineCode, expirationDate);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
MessageBox(hwnd, "License.data generated successfully!", "Success", MB_OK);
|
MessageBox(hwnd, "License.data generated successfully!", "Success", MB_OK);
|
||||||
// Re-validate and update the status label
|
|
||||||
UpdateValidationStatus(hwnd);
|
UpdateValidationStatus(hwnd);
|
||||||
} else {
|
} else {
|
||||||
MessageBox(hwnd, "Failed to generate license file!", "Error", MB_ICONERROR);
|
MessageBox(hwnd, "Failed to generate license file!", "Error", MB_ICONERROR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IDC_DEC_BUTTON: {
|
||||||
|
char encryptedCode[64];
|
||||||
|
GetWindowText(hDecInputEdit, encryptedCode, sizeof(encryptedCode));
|
||||||
|
int len = strlen(encryptedCode);
|
||||||
|
if (strlen(encryptedCode) != 30) {
|
||||||
|
MessageBox(hwnd, "Please enter a valid 32-character encrypted code.", "Error", MB_ICONERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char decryptedResult[256];
|
||||||
|
int result = DecryptCodeAndGetMachineCode(encryptedCode, decryptedResult, sizeof(decryptedResult));
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
SetWindowText(hDecOutputEdit, decryptedResult);
|
||||||
|
// Also copy the result to the generation input box for convenience
|
||||||
|
SetWindowText(hGenMachineCodeEdit, decryptedResult);
|
||||||
|
} else {
|
||||||
|
SetWindowText(hDecOutputEdit, ""); // Clear previous result
|
||||||
|
MessageBox(hwnd, "Decryption failed. The code is invalid or corrupted.", "Error", MB_ICONERROR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -132,4 +173,4 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8,68 +8,69 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <random>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
// 全局变量来存储机器码和密钥,避免重复计算
|
// --- START: Internal Encryption Helpers ---
|
||||||
static std::string machineCode_cache;
|
|
||||||
static std::string licenseKey_cache;
|
|
||||||
static std::string expiration_date_str = "2099-12-31"; // 默认永久
|
|
||||||
|
|
||||||
// 内部函数,用于初始化缓存
|
// Helper to convert a hex string to a vector of bytes
|
||||||
void InitializeCache() {
|
static std::vector<unsigned char> hex_string_to_bytes(const std::string& hex) {
|
||||||
if (machineCode_cache.empty()) {
|
std::vector<unsigned char> bytes;
|
||||||
machineCode_cache = getMachineCode();
|
if (hex.length() % 2 != 0) return bytes;
|
||||||
}
|
for (unsigned int i = 0; i < hex.length(); i += 2) {
|
||||||
if (licenseKey_cache.empty()) {
|
std::string byteString = hex.substr(i, 2);
|
||||||
licenseKey_cache = picosha2::hash256_hex_string(machineCode_cache).substr(0, 32); // Truncate to 32 chars
|
bytes.push_back((unsigned char)strtol(byteString.c_str(), NULL, 16));
|
||||||
}
|
}
|
||||||
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Encryption/Decryption Helpers ---
|
// Helper to convert a vector of bytes to a hex string
|
||||||
|
static std::string bytes_to_hex_string(const std::vector<unsigned char>& bytes) {
|
||||||
// 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;
|
std::stringstream ss;
|
||||||
ss << std::hex << std::setfill('0');
|
ss << std::hex << std::uppercase << std::setfill('0');
|
||||||
for (unsigned char c : in) {
|
for (unsigned char byte : bytes) {
|
||||||
ss << std::setw(2) << static_cast<int>(c);
|
ss << std::setw(2) << static_cast<int>(byte);
|
||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a hex string back to a normal string
|
// Generates a pseudo-random keystream from a 16-bit seed (Nonce)
|
||||||
std::string hex_to_string(const std::string& in) {
|
static void generate_keystream(uint16_t seed, std::vector<unsigned char>& keystream, size_t len) {
|
||||||
std::string output;
|
std::mt19937 gen(seed);
|
||||||
if (in.length() % 2 != 0) {
|
std::uniform_int_distribution<> distrib(0, 255);
|
||||||
return ""; // Invalid hex
|
keystream.clear();
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
keystream.push_back(static_cast<unsigned char>(distrib(gen)));
|
||||||
}
|
}
|
||||||
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);
|
// XORs a vector of bytes with a keystream
|
||||||
output.push_back(byte);
|
static std::vector<unsigned char> xor_bytes(const std::vector<unsigned char>& data, const std::vector<unsigned char>& key) {
|
||||||
|
std::vector<unsigned char> output;
|
||||||
|
size_t len = std::min(data.size(), key.size());
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
output.push_back(data[i] ^ key[i]);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- END: Internal Encryption Helpers ---
|
||||||
|
|
||||||
// C-style string return needs to be managed carefully.
|
|
||||||
// We use static buffers here, which is not thread-safe but simple.
|
// --- Global Caches and Buffers ---
|
||||||
// For a real-world app, consider returning std::string or managing memory better.
|
static std::string machineCode_cache;
|
||||||
static char machineCode_cstr[256];
|
static char machineCode_cstr[256];
|
||||||
static char licenseKey_cstr[256];
|
static char encryptedCode_cstr[33]; // 32 chars + null terminator
|
||||||
|
static char decryptedCode_cstr[256];
|
||||||
|
|
||||||
|
// Internal function to initialize the machine code cache
|
||||||
|
void InitializeCache() {
|
||||||
|
if (machineCode_cache.empty()) {
|
||||||
|
machineCode_cache = getMachineCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Core API Implementations ---
|
||||||
|
|
||||||
const char* GetMachineCode() {
|
const char* GetMachineCode() {
|
||||||
InitializeCache();
|
InitializeCache();
|
||||||
@ -78,97 +79,42 @@ const char* GetMachineCode() {
|
|||||||
return machineCode_cstr;
|
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) {
|
int GenerateLicenseFileFromCode(const char* machine_code, const char* expiration_date) {
|
||||||
if (!machine_code || !expiration_date) {
|
if (!machine_code || !expiration_date) {
|
||||||
return 1; // 失败
|
return 1; // Failure
|
||||||
}
|
}
|
||||||
std::string mc_str(machine_code);
|
|
||||||
|
std::string mc_str(machine_code);
|
||||||
|
//std::transform(mc_str.begin(), mc_str.end(), std::toupper);
|
||||||
std::string exp_str(expiration_date);
|
std::string exp_str(expiration_date);
|
||||||
|
|
||||||
// 1. Encrypt the expiration date
|
std::string xor_key = picosha2::hash256_hex_string(mc_str).substr(0, 32);
|
||||||
std::string xor_key = generate_xor_key(mc_str);
|
|
||||||
std::string encrypted_date = xor_string(exp_str, xor_key);
|
std::string encrypted_date;
|
||||||
std::string encrypted_date_hex = string_to_hex(encrypted_date);
|
for (size_t i = 0; i < exp_str.size(); ++i) {
|
||||||
|
encrypted_date += exp_str[i] ^ xor_key[i % xor_key.length()];
|
||||||
|
}
|
||||||
|
std::string encrypted_date_hex = bytes_to_hex_string(std::vector<unsigned char>(encrypted_date.begin(), encrypted_date.end()));
|
||||||
|
|
||||||
// 2. Create a signature of the machine code and the *encrypted* date
|
|
||||||
std::string data_to_sign = mc_str + encrypted_date_hex;
|
std::string data_to_sign = mc_str + encrypted_date_hex;
|
||||||
std::string signature = picosha2::hash256_hex_string(data_to_sign);
|
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");
|
std::ofstream license_file("License.data");
|
||||||
if (!license_file.is_open()) {
|
if (!license_file.is_open()) {
|
||||||
return 1; // 失败
|
return 1; // Failure
|
||||||
}
|
}
|
||||||
|
|
||||||
license_file << encrypted_date_hex << std::endl;
|
license_file << encrypted_date_hex << std::endl;
|
||||||
license_file << signature << std::endl;
|
license_file << signature << std::endl;
|
||||||
license_file.close();
|
license_file.close();
|
||||||
|
|
||||||
return 0; // 成功
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
int ValidateLicenseFile() {
|
int ValidateLicenseFile() {
|
||||||
std::ifstream license_file("License.data");
|
std::ifstream license_file("License.data");
|
||||||
if (!license_file.is_open()) {
|
if (!license_file.is_open()) {
|
||||||
return 1; // 失败 - 文件不存在
|
return 1; // Failure - file not found
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file_encrypted_date_hex;
|
std::string file_encrypted_date_hex;
|
||||||
@ -178,37 +124,98 @@ int ValidateLicenseFile() {
|
|||||||
license_file.close();
|
license_file.close();
|
||||||
|
|
||||||
if (file_encrypted_date_hex.empty() || file_signature.empty()) {
|
if (file_encrypted_date_hex.empty() || file_signature.empty()) {
|
||||||
return 1; // 失败 - 文件格式错误
|
return 1; // Failure - format error
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Verify the signature first to ensure integrity
|
InitializeCache();
|
||||||
InitializeCache(); // Loads local machine code into machineCode_cache
|
|
||||||
std::string data_to_verify = machineCode_cache + file_encrypted_date_hex;
|
std::string data_to_verify = machineCode_cache + file_encrypted_date_hex;
|
||||||
std::string expected_signature = picosha2::hash256_hex_string(data_to_verify);
|
std::string expected_signature = picosha2::hash256_hex_string(data_to_verify);
|
||||||
|
|
||||||
if (file_signature != expected_signature) {
|
if (file_signature != expected_signature) {
|
||||||
return 1; // 失败 - 签名不匹配, 文件被篡改或不属于此机器
|
return 1; // Failure - signature mismatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Decrypt the date
|
std::string xor_key = picosha2::hash256_hex_string(machineCode_cache).substr(0, 32);
|
||||||
std::string xor_key = generate_xor_key(machineCode_cache);
|
std::vector<unsigned char> encrypted_date_bytes = hex_string_to_bytes(file_encrypted_date_hex);
|
||||||
std::string encrypted_date = hex_to_string(file_encrypted_date_hex);
|
std::string encrypted_date(encrypted_date_bytes.begin(), encrypted_date_bytes.end());
|
||||||
std::string decrypted_date = xor_string(encrypted_date, xor_key);
|
std::string decrypted_date;
|
||||||
|
for (size_t i = 0; i < encrypted_date.size(); ++i) {
|
||||||
|
decrypted_date += encrypted_date[i] ^ xor_key[i % xor_key.length()];
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Check the expiration date
|
|
||||||
std::tm tm = {};
|
std::tm tm = {};
|
||||||
std::stringstream ss(decrypted_date);
|
std::stringstream ss(decrypted_date);
|
||||||
ss >> std::get_time(&tm, "%Y-%m-%d");
|
ss >> std::get_time(&tm, "%Y-%m-%d");
|
||||||
if (ss.fail()) {
|
if (ss.fail()) {
|
||||||
return 1; // 失败 - 日期格式损坏
|
return 1; // Failure - date format corrupted
|
||||||
}
|
}
|
||||||
|
|
||||||
auto expiration_time = std::chrono::system_clock::from_time_t(std::mktime(&tm));
|
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);
|
expiration_time += std::chrono::hours(23) + std::chrono::minutes(59) + std::chrono::seconds(59);
|
||||||
|
|
||||||
if (std::chrono::system_clock::now() > expiration_time) {
|
if (std::chrono::system_clock::now() > expiration_time) {
|
||||||
return 2; // 过期
|
return 2; // Expired
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; // 成功
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- New Encryption/Decryption API Implementations ---
|
||||||
|
|
||||||
|
const char* GenerateEncryptedCode() {
|
||||||
|
InitializeCache();
|
||||||
|
std::string machineCodeStr = machineCode_cache;
|
||||||
|
machineCodeStr.erase(std::remove(machineCodeStr.begin(), machineCodeStr.end(), '-'), machineCodeStr.end());
|
||||||
|
std::vector<unsigned char> mc_bytes = hex_string_to_bytes(machineCodeStr);
|
||||||
|
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
std::uniform_int_distribution<uint16_t> distrib(0, 65535);
|
||||||
|
uint16_t nonce = distrib(gen);
|
||||||
|
|
||||||
|
std::vector<unsigned char> keystream;
|
||||||
|
generate_keystream(nonce, keystream, 14);
|
||||||
|
|
||||||
|
std::vector<unsigned char> encrypted_mc = xor_bytes(mc_bytes, keystream);
|
||||||
|
|
||||||
|
std::vector<unsigned char> final_payload;
|
||||||
|
final_payload.insert(final_payload.end(), encrypted_mc.begin(), encrypted_mc.begin() + 7);
|
||||||
|
final_payload.push_back(static_cast<unsigned char>(nonce & 0xFF));
|
||||||
|
final_payload.push_back(static_cast<unsigned char>((nonce >> 8) & 0xFF));
|
||||||
|
final_payload.insert(final_payload.end(), encrypted_mc.begin() + 7, encrypted_mc.end());
|
||||||
|
|
||||||
|
std::string final_code = bytes_to_hex_string(final_payload);
|
||||||
|
|
||||||
|
strncpy_s(encryptedCode_cstr, final_code.c_str(), sizeof(encryptedCode_cstr) - 1);
|
||||||
|
encryptedCode_cstr[sizeof(encryptedCode_cstr) - 1] = '\0';
|
||||||
|
return encryptedCode_cstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecryptCodeAndGetMachineCode(const char* encrypted_code, char* decrypted_machine_code, int buffer_size) {
|
||||||
|
if (!encrypted_code || strlen(encrypted_code) != 32) {
|
||||||
|
return 1; // Failure: invalid input
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> final_payload = hex_string_to_bytes(encrypted_code);
|
||||||
|
if (final_payload.size() != 16) {
|
||||||
|
return 1; // Failure: invalid hex string
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t nonce = final_payload[7] | (static_cast<uint16_t>(final_payload[8]) << 8);
|
||||||
|
|
||||||
|
std::vector<unsigned char> encrypted_mc;
|
||||||
|
encrypted_mc.insert(encrypted_mc.end(), final_payload.begin(), final_payload.begin() + 7);
|
||||||
|
encrypted_mc.insert(encrypted_mc.end(), final_payload.begin() + 9, final_payload.end());
|
||||||
|
|
||||||
|
std::vector<unsigned char> keystream;
|
||||||
|
generate_keystream(nonce, keystream, 14);
|
||||||
|
|
||||||
|
std::vector<unsigned char> decrypted_mc_bytes = xor_bytes(encrypted_mc, keystream);
|
||||||
|
|
||||||
|
std::string machine_code_hex = bytes_to_hex_string(decrypted_mc_bytes);
|
||||||
|
|
||||||
|
// Return the pure hex machine code, without the hyphen.
|
||||||
|
strncpy_s(decrypted_machine_code, buffer_size, machine_code_hex.c_str(), _TRUNCATE);
|
||||||
|
|
||||||
|
return 0; // Success
|
||||||
|
}
|
||||||
58
src/test_encryption.cpp
Normal file
58
src/test_encryption.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "registration_api.h"
|
||||||
|
|
||||||
|
// Helper function to print test results
|
||||||
|
void print_test_result(const std::string& test_name, bool success) {
|
||||||
|
std::cout << "- Test: " << test_name << "... "
|
||||||
|
<< (success ? "PASSED" : "FAILED") << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "--- Running Encryption/Decryption API Test --- \n" << std::endl;
|
||||||
|
|
||||||
|
// --- Test 1: Get Original Machine Code ---
|
||||||
|
const char* original_mc_raw = GetMachineCode();
|
||||||
|
std::string original_mc(original_mc_raw);
|
||||||
|
std::cout << "Original Machine Code: " << original_mc << std::endl;
|
||||||
|
print_test_result("GetMachineCode() is not empty", !original_mc.empty());
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// --- Test 2: Generate Encrypted Code ---
|
||||||
|
const char* encrypted_code_raw = GenerateEncryptedCode();
|
||||||
|
std::string encrypted_code(encrypted_code_raw);
|
||||||
|
std::cout << "Generated Encrypted Code: " << encrypted_code << std::endl;
|
||||||
|
print_test_result("GenerateEncryptedCode() returns 32 characters", encrypted_code.length() == 32);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// --- Test 3: Decrypt the Code ---
|
||||||
|
char decrypted_buffer[256];
|
||||||
|
int decryption_result = DecryptCodeAndGetMachineCode(encrypted_code.c_str(), decrypted_buffer, sizeof(decrypted_buffer));
|
||||||
|
std::string decrypted_mc(decrypted_buffer);
|
||||||
|
|
||||||
|
std::cout << "Decrypted Machine Code (no hyphen): " << decrypted_mc << std::endl;
|
||||||
|
print_test_result("DecryptCodeAndGetMachineCode() succeeds", decryption_result == 0);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// --- Test 4: Compare Original and Decrypted ---
|
||||||
|
std::string original_mc_no_hyphen = original_mc;
|
||||||
|
original_mc_no_hyphen.erase(std::remove(original_mc_no_hyphen.begin(), original_mc_no_hyphen.end(), '-'), original_mc_no_hyphen.end());
|
||||||
|
|
||||||
|
std::cout << "Original (no hyphen): " << original_mc_no_hyphen << std::endl;
|
||||||
|
std::cout << "Decrypted: " << decrypted_mc << std::endl;
|
||||||
|
|
||||||
|
bool match = (original_mc_no_hyphen == decrypted_mc);
|
||||||
|
print_test_result("Decrypted code matches original", match);
|
||||||
|
std::cout << "\n--------------------------------------------------" << std::endl;
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
std::cout << "\nSUCCESS: The encryption and decryption functions are working correctly.\n" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "\nFAILURE: The decrypted code does NOT match the original.\n" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,7 +19,7 @@ void print_status(int code) {
|
|||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
// --- Step 1: Generate a valid license file ---
|
// --- Step 1: Generate a valid license file ---
|
||||||
std::cout << "--- Step 1: Generating a valid license file for this machine ---" << std::endl;
|
std::cout << "--- Step 1: Generating a valid license file for this machine ---" << std::endl;
|
||||||
const char* machine_code = GetMachineCode();
|
const char* machine_code = GenerateEncryptedCode();
|
||||||
if (!machine_code || std::string(machine_code).empty()) {
|
if (!machine_code || std::string(machine_code).empty()) {
|
||||||
std::cerr << "!! ERROR: Could not get machine code." << std::endl;
|
std::cerr << "!! ERROR: Could not get machine code." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
@ -28,8 +28,9 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
const char* future_date = "2099-12-31";
|
const char* future_date = "2099-12-31";
|
||||||
std::cout << "Generating license with expiration date: " << future_date << std::endl;
|
std::cout << "Generating license with expiration date: " << future_date << std::endl;
|
||||||
|
char code[33] = { 0 };
|
||||||
int gen_result = GenerateLicenseFileFromCode(machine_code, future_date);
|
DecryptCodeAndGetMachineCode(machine_code, code, 33);
|
||||||
|
int gen_result = GenerateLicenseFileFromCode(code, future_date);
|
||||||
if (gen_result == 0) {
|
if (gen_result == 0) {
|
||||||
std::cout << "License.data generated successfully." << std::endl;
|
std::cout << "License.data generated successfully." << std::endl;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user