mirror of
https://github.com/DoubleLabyrinth/navicat-keygen.git
synced 2019-12-02 05:10:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4af61a272b | ||
|
|
0b3bb309b2 | ||
|
|
2f04767075 | ||
|
|
24464f59a0 | ||
|
|
c01bb7f6a5 |
@@ -28,7 +28,7 @@
|
||||
|
||||
* __Offline Activation Request Information__
|
||||
|
||||
It is just a JSON-style ASCII string which contains 3 items. Respectively they are `"K"`, `"DI"` and `"P"`, which represent __snKey__, __checksum__ (related with your machine and OS), __Platform__ (Appropriately speaking, it should be OS Type).
|
||||
It is just a JSON-style ASCII string which contains 3 items. Respectively they are `"K"`, `"DI"` and `"P"`, which represent __snKey__, __DeviceIdentifier__ (related with your machine), __Platform__ (Appropriately speaking, it should be OS Type).
|
||||
|
||||
Like:
|
||||
> {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
`"K"` and `"DI"` has the same meaning mentioned in __Offline Activation Request Information__ and must be same with the corresponding items in __Offline Activation Request Information__.
|
||||
|
||||
`"N"`, `"O"`, `"T"` represent __Name__, __Organization__, __Time__ respectively. __Name__ and __Organization__ are string and the type of __Time__ is unknown.
|
||||
`"N"`, `"O"`, `"T"` represent __Name__, __Organization__, __Time__ respectively. __Name__ and __Organization__ are string and the type of __Time__ can be string or integer (Thanks for discoveries from @Wizr, issue #10).
|
||||
|
||||
`"T"` can be omitted.
|
||||
|
||||
@@ -66,9 +66,19 @@
|
||||
~~_`May change when Navicat product changes. Uncertain yet.`_~~
|
||||
_`Must change when Navicat product changes. Confirmed yet.`_
|
||||
|
||||
For __Navicat 12 x64 Simplified Chinese version__: They must be `0xCE` and `0x32` respectively.
|
||||
For __Navicat 12 x64 Traditional Chinese version__: They must be `0xAA` and `0x99` respectively.
|
||||
For __Navicat 11 x64 Simplified Chinese version__: They must be `0xCE` and `0x32` respectively.
|
||||
| Language | data[5] | data[6] | Discoverer |
|
||||
|------------|-----------|-----------|-----------------|
|
||||
| English | 0xAC | 0x88 | |
|
||||
| 简体中文 | 0xCE | 0x32 | |
|
||||
| 繁體中文 | 0xAA | 0x99 | |
|
||||
| 日本語 | 0xAD | 0x82 | @dragonflylee |
|
||||
| Polski | 0xBB | 0x55 | @dragonflylee |
|
||||
| Español | 0xAE | 0x10 | @dragonflylee |
|
||||
| Français | 0xFA | 0x20 | @Deltafox79 |
|
||||
| Deutsch | 0xB1 | 0x60 | @dragonflylee |
|
||||
| 한국어 | 0xB5 | 0x60 | @dragonflylee |
|
||||
| Русский | 0xEE | 0x16 | @dragonflylee |
|
||||
| Português | 0xCD | 0x49 | @dragonflylee |
|
||||
|
||||
According to __Navicat 12 for Mac x64__ version, what IDA 7.0 indicates is that this two bytes are product signature.
|
||||
|
||||
@@ -154,3 +164,37 @@
|
||||
4. Encode 256-byte-long data by Base64. The result is __Activation Code__.
|
||||
|
||||
5. Input __Activation Code__, then offline activation is done.
|
||||
|
||||
## 4. How to use
|
||||
1. Build patcher and keygen.
|
||||
|
||||
2. Replace __Navicat Activation Public Key__ in `navicat.exe`.
|
||||
Example:
|
||||
|
||||
```bash
|
||||
E:\GitHub\navicat-keygen\x64\Release>navicat-patcher.exe "D:\Program Files\PremiumSoft\Navicat Premium 12\navicat.exe"
|
||||
D:\Program Files\PremiumSoft\Navicat Premium 12\navicat.exe has been backed up.
|
||||
Public key has been replaced.
|
||||
Success!
|
||||
|
||||
```
|
||||
|
||||
You will get `RegPrivateKey.pem` file at current directory.
|
||||
|
||||
3. Then in console:
|
||||
|
||||
```bash
|
||||
E:\GitHub\navicat-keygen\x64\Release>navicat-keygen.exe RegPrivateKey.pem
|
||||
|
||||
```
|
||||
|
||||
You will get a __snKey__ and be asked to input your name and organization.
|
||||
Just input and then you will be asked to input the request code. Now __DO NOT CLOSE KEYGEN__.
|
||||
|
||||
4. Disconnect network and open Navicat Premium, find and click `Registration`. Then input `Registration Key` by snKey that keygen gave. Then click `Activate`.
|
||||
|
||||
5. Generally online activation will failed and Navicat will ask you do `Manual Activation`, just choose it.
|
||||
|
||||
6. Copy your request code and paste it in keygen. Input empty line to tell keygen that your input ends.
|
||||
|
||||
7. Then you will get activation code which looks like a Base64 string. Just copy it and paste it in Navicat `Manual Activation` window, then click Activate. If nothing is wrong, activation should be done successfully.
|
||||
|
||||
+165
-158
@@ -2,9 +2,8 @@
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#ifndef UNICODE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
@@ -16,54 +15,94 @@
|
||||
#pragma comment(lib, "libcrypto.lib")
|
||||
|
||||
#define NAVICAT_12
|
||||
#define NAVICAT_CHS
|
||||
|
||||
void GenerateSnKey(char(&SnKey)[16]) {
|
||||
static char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
static DES_cblock DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
|
||||
BYTE temp_snKey[10] = { 0x68, 0x2a }; // must start with 0x68, 0x2a
|
||||
temp_snKey[2] = rand();
|
||||
temp_snKey[3] = rand();
|
||||
temp_snKey[4] = rand();
|
||||
temp_snKey[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
// Must be 0xAA for Traditional Chinese version.
|
||||
BYTE temp_SnKey[10] = { 0x68, 0x2a }; // must start with 0x68, 0x2a
|
||||
temp_SnKey[2] = rand();
|
||||
temp_SnKey[3] = rand();
|
||||
temp_SnKey[4] = rand();
|
||||
|
||||
temp_snKey[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
// Must be 0x99 for Traditional Chinese version.
|
||||
#if defined(NAVICAT_ENG)
|
||||
temp_SnKey[5] = 0xAC; // Must be 0xAC for English version.
|
||||
temp_SnKey[6] = 0x88; // Must be 0x88 for English version.
|
||||
#elif defined(NAVICAT_CHS)
|
||||
temp_SnKey[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
temp_SnKey[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
#elif defined(NAVICAT_CHT)
|
||||
temp_SnKey[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
|
||||
temp_SnKey[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
|
||||
#elif defined(NAVICAT_JAP)
|
||||
temp_SnKey[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_POL)
|
||||
temp_SnKey[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_SPA)
|
||||
temp_SnKey[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_FRE)
|
||||
temp_SnKey[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
|
||||
temp_SnKey[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
|
||||
#elif defined(NAVICAT_GER)
|
||||
temp_SnKey[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_KOR)
|
||||
temp_SnKey[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_RUS)
|
||||
temp_SnKey[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
|
||||
#elif defined(NAVICAT_POR)
|
||||
temp_SnKey[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
|
||||
temp_SnKey[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
|
||||
#else
|
||||
#error "Navicat product type is not specified."
|
||||
#endif
|
||||
|
||||
#if defined(NAVICAT_12)
|
||||
temp_snKey[7] = 0x65; // 0x65 - commercial, 0x66 - non-commercial
|
||||
temp_snKey[8] = 0xC0; // High 4-bits = version number. Low 4-bits doesn't know, but can be used to delay activation time.
|
||||
temp_SnKey[7] = 0x65; // 0x65 - commercial, 0x66 - non-commercial
|
||||
temp_SnKey[8] = 0xC0; // High 4-bits = version number. Low 4-bits doesn't know, but can be used to delay activation time.
|
||||
#elif defined(NAVICAT_11)
|
||||
temp_snKey[7] = 0x15; // 0x15 - commercial, 0x16 - non-commercial
|
||||
temp_snKey[8] = 0xB0; // High 4-bits = version number. Low 4-bits doesn't know, but can be used to delay activation time.
|
||||
temp_SnKey[7] = 0x15; // 0x15 - commercial, 0x16 - non-commercial
|
||||
temp_SnKey[8] = 0xB0; // High 4-bits = version number. Low 4-bits doesn't know, but can be used to delay activation time.
|
||||
#else
|
||||
#error "Navicat version is not specified."
|
||||
#endif
|
||||
temp_snKey[9] = 0x70; // 0xfd, 0xfc, 0xfb if you want to use not-for-resale license.
|
||||
temp_SnKey[9] = 0x32; // 0xFB is Not-For-Resale-30-days license.
|
||||
// 0xFC is Not-For-Resale-90-days license.
|
||||
// 0xFD is Not-For-Resale-365-days license.
|
||||
// 0xFE is Not-For-Resale license.
|
||||
// 0xFF is Site license.
|
||||
// Must not be 0x00. 0x01-0xFA is ok.
|
||||
|
||||
DES_key_schedule schedule;
|
||||
DES_set_key_unchecked(&DESKey, &schedule);
|
||||
DES_cblock enc_temp_snKey;
|
||||
|
||||
DES_ecb_encrypt(reinterpret_cast<const_DES_cblock*>(temp_snKey + 2), &enc_temp_snKey, &schedule, DES_ENCRYPT);
|
||||
memmove_s(temp_snKey + 2, sizeof(enc_temp_snKey), enc_temp_snKey, sizeof(enc_temp_snKey));
|
||||
DES_ecb_encrypt(reinterpret_cast<const_DES_cblock*>(temp_SnKey + 2), &enc_temp_snKey, &schedule, DES_ENCRYPT);
|
||||
memmove_s(temp_SnKey + 2, sizeof(enc_temp_snKey), enc_temp_snKey, sizeof(enc_temp_snKey));
|
||||
|
||||
SnKey[0] = EncodeTable[temp_snKey[0] >> 3];
|
||||
SnKey[1] = EncodeTable[(temp_snKey[0] & 0x07) << 2 | temp_snKey[1] >> 6];
|
||||
SnKey[2] = EncodeTable[temp_snKey[1] >> 1 & 0x1F];
|
||||
SnKey[3] = EncodeTable[(temp_snKey[1] & 0x1) << 4 | temp_snKey[2] >> 4];
|
||||
SnKey[4] = EncodeTable[(temp_snKey[2] & 0xF) << 1 | temp_snKey[3] >> 7];
|
||||
SnKey[5] = EncodeTable[temp_snKey[3] >> 2 & 0x1F];
|
||||
SnKey[6] = EncodeTable[temp_snKey[3] << 3 & 0x1F | temp_snKey[4] >> 5];
|
||||
SnKey[7] = EncodeTable[temp_snKey[4] & 0x1F];
|
||||
SnKey[0] = EncodeTable[temp_SnKey[0] >> 3];
|
||||
SnKey[1] = EncodeTable[(temp_SnKey[0] & 0x07) << 2 | temp_SnKey[1] >> 6];
|
||||
SnKey[2] = EncodeTable[temp_SnKey[1] >> 1 & 0x1F];
|
||||
SnKey[3] = EncodeTable[(temp_SnKey[1] & 0x1) << 4 | temp_SnKey[2] >> 4];
|
||||
SnKey[4] = EncodeTable[(temp_SnKey[2] & 0xF) << 1 | temp_SnKey[3] >> 7];
|
||||
SnKey[5] = EncodeTable[temp_SnKey[3] >> 2 & 0x1F];
|
||||
SnKey[6] = EncodeTable[temp_SnKey[3] << 3 & 0x1F | temp_SnKey[4] >> 5];
|
||||
SnKey[7] = EncodeTable[temp_SnKey[4] & 0x1F];
|
||||
|
||||
SnKey[8] = EncodeTable[temp_snKey[5] >> 3];
|
||||
SnKey[9] = EncodeTable[(temp_snKey[5] & 0x07) << 2 | temp_snKey[6] >> 6];
|
||||
SnKey[10] = EncodeTable[temp_snKey[6] >> 1 & 0x1F];
|
||||
SnKey[11] = EncodeTable[(temp_snKey[6] & 0x1) << 4 | temp_snKey[7] >> 4];
|
||||
SnKey[12] = EncodeTable[(temp_snKey[7] & 0xF) << 1 | temp_snKey[8] >> 7];
|
||||
SnKey[13] = EncodeTable[temp_snKey[8] >> 2 & 0x1F];
|
||||
SnKey[14] = EncodeTable[temp_snKey[8] << 3 & 0x1F | temp_snKey[9] >> 5];
|
||||
SnKey[15] = EncodeTable[temp_snKey[9] & 0x1F];
|
||||
SnKey[8] = EncodeTable[temp_SnKey[5] >> 3];
|
||||
SnKey[9] = EncodeTable[(temp_SnKey[5] & 0x07) << 2 | temp_SnKey[6] >> 6];
|
||||
SnKey[10] = EncodeTable[temp_SnKey[6] >> 1 & 0x1F];
|
||||
SnKey[11] = EncodeTable[(temp_SnKey[6] & 0x1) << 4 | temp_SnKey[7] >> 4];
|
||||
SnKey[12] = EncodeTable[(temp_SnKey[7] & 0xF) << 1 | temp_SnKey[8] >> 7];
|
||||
SnKey[13] = EncodeTable[temp_SnKey[8] >> 2 & 0x1F];
|
||||
SnKey[14] = EncodeTable[temp_SnKey[8] << 3 & 0x1F | temp_SnKey[9] >> 5];
|
||||
SnKey[15] = EncodeTable[temp_SnKey[9] & 0x1F];
|
||||
|
||||
_tprintf_s(TEXT("\r\n"));
|
||||
_tprintf_s(TEXT("SnKey:\r\n"));
|
||||
@@ -75,25 +114,30 @@ BOOL GenerateLicense(RSA* RSAPrivateKey,
|
||||
const char* SnKey,
|
||||
const char* Name,
|
||||
const char* Organization,
|
||||
const char* DI) {
|
||||
const char* DeviceIdentifier) {
|
||||
|
||||
char LicenseJson[2048 / 8] = { };
|
||||
#if defined(NAVICAT_12)
|
||||
sprintf_s(LicenseJson, "{\"K\":\"%.16s\", \"N\":\"%s\", \"O\":\"%s\", \"DI\":\"%s\"}", SnKey, Name, Organization, DI);
|
||||
sprintf_s(LicenseJson, "{\"K\":\"%.16s\", \"N\":\"%s\", \"O\":\"%s\", \"DI\":\"%s\"}", SnKey, Name, Organization, DeviceIdentifier);
|
||||
#elif defined(NAVICAT_11)
|
||||
sprintf_s(LicenseJson, "{\"K\":\"%.16s\", \"N\":\"%s\", \"O\":\"%s\"}", SnKey, Name, Organization);
|
||||
#else
|
||||
#error "Navicat version is not specified."
|
||||
#endif
|
||||
unsigned char License[2048 / 8] = { };
|
||||
RSA_private_encrypt(strlen(LicenseJson),
|
||||
reinterpret_cast<uint8_t*>(LicenseJson),
|
||||
License,
|
||||
RSAPrivateKey,
|
||||
RSA_PKCS1_PADDING);
|
||||
unsigned char EncryptedLicenseData[2048 / 8] = { };
|
||||
if (RSA_private_encrypt(static_cast<int>(strlen(LicenseJson)),
|
||||
reinterpret_cast<uint8_t*>(LicenseJson),
|
||||
EncryptedLicenseData,
|
||||
RSAPrivateKey,
|
||||
RSA_PKCS1_PADDING) == -1) {
|
||||
_tprintf_s(TEXT("Failed to encrypt license data.\r\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(NAVICAT_12)
|
||||
DWORD LicenseStringLength = 1024;
|
||||
TCHAR LicenseString[1024] = { };
|
||||
if (!CryptBinaryToString(License, sizeof(License), CRYPT_STRING_BASE64, LicenseString, &LicenseStringLength)) {
|
||||
if (!CryptBinaryToString(EncryptedLicenseData, sizeof(EncryptedLicenseData), CRYPT_STRING_BASE64, LicenseString, &LicenseStringLength)) {
|
||||
_tprintf_s(TEXT("Cannot get Base64 string. CODE: 0x%08x\r\n"), GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
@@ -102,10 +146,13 @@ BOOL GenerateLicense(RSA* RSAPrivateKey,
|
||||
return TRUE;
|
||||
#elif defined(NAVICAT_11)
|
||||
HANDLE hLicenseFile = CreateFile(TEXT("license_file"), GENERIC_ALL, NULL, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (hLicenseFile == NULL)
|
||||
if (hLicenseFile == NULL) {
|
||||
_tprintf_s(TEXT("Failed to create \"license_file\".\r\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!WriteFile(hLicenseFile, License, sizeof(License), nullptr, nullptr)) {
|
||||
if (!WriteFile(hLicenseFile, EncryptedLicenseData, sizeof(EncryptedLicenseData), nullptr, nullptr)) {
|
||||
_tprintf_s(TEXT("Failed to write \"license_file\".\r\n"));
|
||||
CloseHandle(hLicenseFile);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -119,152 +166,112 @@ int _tmain(int argc, TCHAR* argv[]) {
|
||||
if (argc != 2) {
|
||||
_tprintf_s(TEXT("Usage:\r\n"));
|
||||
_tprintf_s(TEXT(" navicat-keygen.exe <RSA-2048 PrivateKey(PEM file)>\r\n"));
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
srand(time(nullptr));
|
||||
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
#ifdef UNICODE
|
||||
char pem_file_path[256] = { };
|
||||
char pem_file_path[MAX_PATH] = { };
|
||||
sprintf_s(pem_file_path, "%S", argv[1]);
|
||||
#else
|
||||
char* pem_file_path = argv[1];
|
||||
#endif
|
||||
|
||||
RSA* PrivateKey = nullptr;
|
||||
BIO* PrivateKeyFile = BIO_new(BIO_s_file());
|
||||
BIO_read_filename(PrivateKeyFile, pem_file_path);
|
||||
PrivateKey = PEM_read_bio_RSAPrivateKey(PrivateKeyFile, nullptr, nullptr, nullptr);
|
||||
BIO_free_all(PrivateKeyFile);
|
||||
{
|
||||
BIO* PrivateKeyFile = BIO_new(BIO_s_file());
|
||||
BIO_read_filename(PrivateKeyFile, pem_file_path);
|
||||
PrivateKey = PEM_read_bio_RSAPrivateKey(PrivateKeyFile, nullptr, nullptr, nullptr);
|
||||
BIO_free_all(PrivateKeyFile);
|
||||
}
|
||||
|
||||
if (PrivateKey == nullptr) {
|
||||
_tprintf_s(TEXT("Failed to load private key.\r\n"));
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TCHAR tName[64] = { };
|
||||
TCHAR tOrganization[64] = { };
|
||||
{
|
||||
DWORD ReadCount;
|
||||
|
||||
_tprintf_s(TEXT("Your name: "));
|
||||
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), tName, 64, &ReadCount, nullptr);
|
||||
tName[ReadCount - 2] = 0;
|
||||
tName[ReadCount - 1] = 0;
|
||||
_tprintf_s(TEXT("Your organization: "));
|
||||
ReadConsole(GetStdHandle(STD_INPUT_HANDLE), tOrganization, 64, &ReadCount, nullptr);
|
||||
tOrganization[ReadCount - 2] = 0;
|
||||
tOrganization[ReadCount - 1] = 0;
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
char Name[64] = { };
|
||||
char Organization[64] = { };
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
|
||||
tName, _tcslen(tName),
|
||||
Name, 64,
|
||||
NULL,
|
||||
NULL) == 0) {
|
||||
_tprintf_s(TEXT("Failed to convert name to UTF-8. CODE: 0x%08x\r\n"), GetLastError());
|
||||
RSA_free(PrivateKey);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
|
||||
tOrganization, _tcslen(tOrganization),
|
||||
Organization, 64,
|
||||
NULL,
|
||||
NULL) == 0) {
|
||||
_tprintf_s(TEXT("Failed to convert name to UTF-8. CODE: 0x%08x\r\n"), GetLastError());
|
||||
RSA_free(PrivateKey);
|
||||
return GetLastError();
|
||||
}
|
||||
#else
|
||||
char* Name = tName;
|
||||
char* Organization = tOrganization;
|
||||
#endif
|
||||
|
||||
char SnKey[16] = { };
|
||||
GenerateSnKey(SnKey);
|
||||
|
||||
TCHAR Base64String[1024] = { };
|
||||
std::string strName;
|
||||
std::string strOrganization;
|
||||
_tprintf_s(TEXT("Your name: "));
|
||||
std::getline(std::cin, strName);
|
||||
_tprintf_s(TEXT("Your organization: "));
|
||||
std::getline(std::cin, strOrganization);
|
||||
|
||||
#if defined(NAVICAT_12)
|
||||
std::string RequestCode;
|
||||
_tprintf_s(TEXT("Input request code (in Base64), empty line to return:\r\n"));
|
||||
for (TCHAR* cur = Base64String; cur < Base64String + 1024;) {
|
||||
DWORD ReadCount;
|
||||
if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE), cur, Base64String + 1024 - cur, &ReadCount, NULL))
|
||||
while (true) {
|
||||
std::string temp;
|
||||
std::getline(std::cin, temp);
|
||||
if (temp.empty())
|
||||
break;
|
||||
|
||||
cur += ReadCount;
|
||||
#ifdef UNICODE
|
||||
if (*reinterpret_cast<uint32_t*>(cur - 4) == '\r\0\n\0')
|
||||
break;
|
||||
#else
|
||||
if (*reinterpret_cast<uint32_t*>(cur - 4) == '\r\n\r\n')
|
||||
break;
|
||||
#endif
|
||||
RequestCode += temp;
|
||||
}
|
||||
Base64String[1024 - 1] = NULL;
|
||||
|
||||
BYTE enc_request_code[1024] = { };
|
||||
DWORD enc_request_code_length = 1024;
|
||||
if (!CryptStringToBinary(Base64String, NULL, CRYPT_STRING_BASE64, enc_request_code, &enc_request_code_length, NULL, NULL)) {
|
||||
|
||||
BYTE EncryptedRequestData[1024] = { };
|
||||
DWORD EncryptedRequestDataLength = sizeof(EncryptedRequestData);
|
||||
if (!CryptStringToBinaryA(RequestCode.c_str(), NULL, CRYPT_STRING_BASE64, EncryptedRequestData, &EncryptedRequestDataLength, NULL, NULL)) {
|
||||
_tprintf_s(TEXT("Failed to decode Base64 string. CODE: 0x%08x\r\n"), GetLastError());
|
||||
RSA_free(PrivateKey);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
char request_code[1024] = { };
|
||||
if (!RSA_private_decrypt(enc_request_code_length,
|
||||
enc_request_code,
|
||||
reinterpret_cast<BYTE*>(request_code),
|
||||
PrivateKey, RSA_PKCS1_PADDING)) {
|
||||
char RequestData[1024] = { };
|
||||
if (RSA_private_decrypt(EncryptedRequestDataLength,
|
||||
EncryptedRequestData,
|
||||
reinterpret_cast<BYTE*>(RequestData),
|
||||
PrivateKey, RSA_PKCS1_PADDING) == -1) {
|
||||
_tprintf_s(TEXT("Failed to decrypt request code.\r\n"));
|
||||
RSA_free(PrivateKey);
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::cout << "-----------Begin Request Code Data---------------" << std::endl;
|
||||
std::cout << RequestData << std::endl;
|
||||
std::cout << "-----------End Request Code Data---------------" << std::endl;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
std::string strDeviceIdentifier;
|
||||
for (int i = 0, length = static_cast<int>(strlen(RequestData)) - 4; i < length; ++i) {
|
||||
if (RequestData[i] == '"' &&
|
||||
RequestData[i + 1] == 'D' &&
|
||||
RequestData[i + 2] == 'I' &&
|
||||
RequestData[i + 3] == '"') {
|
||||
|
||||
char temp[256] = { };
|
||||
int x = i + 4, j = 0;
|
||||
while (RequestData[x] != '"' && x < length)
|
||||
x++;
|
||||
x++;
|
||||
while (RequestData[x] != '"' && j < 256) {
|
||||
temp[j++] = RequestData[x];
|
||||
x++;
|
||||
}
|
||||
strDeviceIdentifier += temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strDeviceIdentifier.empty()) {
|
||||
_tprintf_s(TEXT("Not a valid request code.\r\n"));
|
||||
RSA_free(PrivateKey);
|
||||
return -3;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef UNICODE
|
||||
_tprintf_s(TEXT("%S\r\n"), request_code);
|
||||
#else
|
||||
_tprintf_s(TEXT("%s\r\n"), request_code);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
if (strlen(request_code) >= 256) {
|
||||
_tprintf_s(TEXT("Not a valid request code.\r\n"));
|
||||
RSA_free(PrivateKey);
|
||||
return -4;
|
||||
}
|
||||
|
||||
char* DI_ptr = request_code;
|
||||
for (; DI_ptr < request_code + 256; DI_ptr++) {
|
||||
if (*reinterpret_cast<uint32_t*>(DI_ptr) == '"ID"') {
|
||||
DI_ptr += 4;
|
||||
while (*DI_ptr++ != '"');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (DI_ptr >= request_code + 256) {
|
||||
_tprintf_s(TEXT("Not a valid request code.\r\n"));
|
||||
RSA_free(PrivateKey);
|
||||
return -5;
|
||||
}
|
||||
|
||||
for (char* ptr = DI_ptr; ptr < request_code + 256; ptr++) {
|
||||
if (*ptr == '"') {
|
||||
*ptr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
GenerateLicense(PrivateKey, SnKey, Name, Organization, DI_ptr);
|
||||
GenerateLicense(PrivateKey, SnKey, strName.c_str(), strOrganization.c_str(), strDeviceIdentifier.c_str());
|
||||
#elif defined(NAVICAT_11)
|
||||
GenerateLicense(PrivateKey, SnKey, strName.c_str(), strOrganization.c_str(), nullptr);
|
||||
#else
|
||||
#error "Navicat version is not specified."
|
||||
#endif
|
||||
|
||||
RSA_free(PrivateKey);
|
||||
return 0;
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>D:\OpenSSL-Win32\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\OpenSSL-Win32\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
@@ -79,6 +81,8 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>D:\OpenSSL-Win32\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\OpenSSL-Win32\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
||||
@@ -37,7 +37,7 @@ BOOL BackupNavicat(PTSTR NavicatFileName) {
|
||||
BOOL ReplaceNavicatPublicKey(HANDLE resUpdater, void* pemPublicKey, size_t length) {
|
||||
return UpdateResource(resUpdater,
|
||||
RT_RCDATA,
|
||||
TEXT("ActivationPubKey"),
|
||||
TEXT("ACTIVATIONPUBKEY"),
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
||||
pemPublicKey, length);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ int _tmain(int argc, TCHAR* argv[]) {
|
||||
EndUpdateResource(hUpdater, FALSE);
|
||||
}
|
||||
|
||||
_tprintf_s(TEXT("Success!.\r\n"));
|
||||
_tprintf_s(TEXT("Success!\r\n"));
|
||||
RSA_free(PrivateKey);
|
||||
return 0;
|
||||
}
|
||||
@@ -71,6 +71,8 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>D:\OpenSSL-Win32\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\OpenSSL-Win32\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
@@ -79,6 +81,8 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>D:\OpenSSL-Win32\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>D:\OpenSSL-Win32\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
|
||||
Reference in New Issue
Block a user