how-does-it-work.md 14 KB

Navicat Keygen - How does it work?

中文版

1. Keyword Explanation.

  • Navicat Activation Public Key

It is a RSA-2048 public key that Navicat used to encrypt or decrypt offline activation information.

It is stored in navicat.exe as a kind of resource called RCData. The resource name is "ACTIVATIONPUBKEY". You can see it by a software called Resource Hacker. The public key is

  -----BEGIN PUBLIC KEY-----  
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I  
  qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv  
  a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF  
  R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2  
  WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt  
  YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ  
  awIDAQAB  
  -----END PUBLIC KEY-----  

If you have the corresponding private key, you can tell me. I would be very appreciated for your generous.

NOTICE:

Start from Navicat Premium 12.0.25, Navicat do not load this public key from resource in navicat.exe. Instead, the public key is stored in libcc.dll and has been encrypted. To avoid being replaced easily, the public key is split into 5 parts:

The following content is discovered from libcc.dll of Navicat Premium x64 12.0.25 Simplified Chinese version. The SHA256 value of libcc.dll is 607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0.

I DO NOT guarantee that offset values are absolutely correct in other versions. But char strings and immediate values are highly possible to be found.

  1. At file offset +0x01A12090 in libcc.dll, stored as char string:

     "D75125B70767B94145B47C1CB3C0755E  
      7CCB8825C5DCE0C58ACF944E08280140  
      9A02472FAFFD1CD77864BB821AE36766  
      FEEDE6A24F12662954168BFA314BD950  
      32B9D82445355ED7BC0B880887D650F5" 
    
  2. At file offset +0x0059D799 in libcc.dll, stored as immediate value in a instruction:

     0xFE 0xEA 0xBC 0x01
    

    In decimal: 29158142

  3. At file offset +0x01A11DA0 in libcc.dll, stored as char string:

     "E1CED09B9C2186BF71A70C0FE2F1E0AE  
      F3BD6B75277AAB20DFAF3D110F75912B  
      FB63AC50EC4C48689D1502715243A79F  
      39FF2DE2BF15CE438FF885745ED54573  
      850E8A9F40EE2FF505EB7476F95ADB78  
      3B28CA374FAC4632892AB82FB3BF4715  
      FCFE6E82D03731FC3762B6AAC3DF1C3B  
      C646FE9CD3C62663A97EE72DB932A301  
      312B4A7633100C8CC357262C39A2B3A6  
      4B224F5276D5EDBDF0804DC3AC4B8351  
      62BB1969EAEBADC43D2511D6E0239287  
      81B167A48273B953378D3D2080CC0677  
      7E8A2364F0234B81064C5C739A8DA28D  
      C5889072BF37685CBC94C2D31D0179AD  
      86D8E3AA8090D4F0B281BE37E0143746  
      E6049CCC06899401264FA471C016A96C  
      79815B55BBC26B43052609D9D175FBCD  
      E455392F10E51EC162F51CF732E6BB39  
      1F56BBFD8D957DF3D4C55B71CEFD54B1  
      9C16D458757373E698D7E693A8FC3981  
      5A8BF03BA05EA8C8778D38F9873D62B4  
      460F41ACF997C30E7C3AF025FA171B5F  
      5AD4D6B15E95C27F6B35AD61875E5505  
      449B4E"
    
  4. At file offset +0x0059D77F in libcc.dll, stored as immediate value in a instruction:

     0x59 0x08 0x01 0x00
    

    In decimal: 67673

  5. At file offset + 0x1A11D8C in libcc.dll, stored as char string:

     "92933"
    

Then output encrypted public key with format "%s%d%s%d%s". The order is the same as it lists:

  D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933

This encrypted public key can be decrypted by my another repo: how-does-navicat-encrypt-password, while the key used is b'23970790'.

Example:

  E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git
  ...
  E:\GitHub>cd how-does-navicat-encrypt-password\python3
  E:\GitHub\how-does-navicat-encrypt-password\python3>python
  Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
  Type "help", "copyright", "credits" or "license" for more information.
  >>> from NavicatCrypto import *
  >>> cipher = Navicat11Crypto(b'23970790')
  >>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933'))
  -----BEGIN PUBLIC KEY-----
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
  qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
  a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
  R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
  WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
  YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
  awIDAQAB
  -----END PUBLIC KEY-----

NOTICE:

Start from Navicat Premium 12.1.11, Navicat do not load the public key through the method I talked before. Of course, the public key is still stored in libcc.dll. When Navicat starts, it encrypts the public key by an 8-bytes-long XOR key and stores the ciphertext in static area. When verifing Activation Code, Navicat will regenerate the 8-bytes-long XOR key and decrypts the ciphertext in static area to get the public key.

In libcc.dll, x64 version, you can find some instructions that looks like:

  xor eax, 'M'
  mov byte_xxxxxx, al
  ...
  xor eax, 'I'
  mov byte_xxxxxx, al
  ...
  xor eax, 'I'
  mov byte_xxxxxx, al
  ...
  xor eax, 'B'
  mov byte_xxxxxx, al
  ...
  xor eax, 'I'
  mov byte_xxxxxx, al
  ...
  xor eax, 'j'
  mov byte_xxxxxx, al
  ...
  ...
  • Request Code

It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of Offline Activation Request Information encrypted by Navicat Activation Public Key.

  • Offline Activation Request Information

It is just a JSON-style ASCII string which contains 3 items. They are "K", "DI" and "P" respectively, which represent snKey, DeviceIdentifier (related with your machine), Platform (OS Type).

Like

  {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
  • Activation Code

It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of the Offline Activation Response Information encrypted by Navicat Activation Private Key. So far, we don't know the official activation private key and we have to replace it in navicat.exe and libcc.dll.

  • Offline Activation Response Information

Just like Offline Activation Request Information, it is also a JSON-style ASCII string. But it contains 5 items. They are "K", "N", "O", "T" and "DI" respectively.

"K" and "DI" has the same meaning that is mentioned in Offline Activation Request Information and must be the same with the corresponding items in Offline Activation Request Information.

"N", "O", "T" represent Name, Organization, Timestamp respectively. Name and Organization are UTF-8 strings and the type of Timestamp can be string or integer. (Thanks for discoveries from @Wizr, issue #10)

"T" can be omitted.

  • snKey

It is a 4-block-long string, while every block is 4-chars-long.

snKey is generated by 10-bytes-long data. In order to explain it easily, I use uint8_t data[10] to represent the 10-bytes-long data.

  1. data[0] and data[1] must be 0x68 and 0x2A respectively.

    These two bytes are Naivcat signature number.

  2. data[2], data[3] and data[4] can be any byte. Just set them whatever you want.

  3. data[5] and data[6] are product language signatures.

    | 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 |

  4. data[7] is Navicat product ID. (Thanks @dragonflylee and @Deltafox79)

    |Product Name |Enterprise|Standard|Educational|Essentials| |----------------------|:--------:|:------:|:---------:|:--------:| |Navicat Report Viewer |0x0B | | | | |Navicat Data Modeler 3| |0x84 |0x85 | | |Navicat Premium |0x65 | |0x66 |0x67 | |Navicat MySQL |0x68 |0x69 |0x6A |0x6B | |Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F | |Navicat Oracle |0x70 |0x71 |0x72 |0x73 | |Navicat SQL Server |0x74 |0x75 |0x76 |0x77 | |Navicat SQLite |0x78 |0x79 |0x7A |0x7B | |Navicat MariaDB |0x7C |0x7D |0x7E |0x7F | |Navicat MongoDB |0x80 |0x81 |0x82 | |

  5. High 4 bits of data[8] represents major version number.

    Low 4 bits is unknown, but we can use it to delay activation deadline. Possible values are 0000 or 0001.

    Example:

    For Navicat 12 x64: High 4 bits must be 1100, which is the binary of number 12.
    For Navicat 11 x64: High 4 bits must be 1011, which is the binary of number 11.

  6. data[9] is unknown, but you can set it by 0xFD, 0xFC or 0xFB if you want to use not-for-resale license.

    According to symbol information in Navicat 12 for Mac x64 version:

    • 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.

After uint8_t data[10] is ready, Navicat uses DES with ECB mode to encrypt the last 8 bytes of uint8_t data[10] which are from data[2] to data[9].

The DES key is:

  unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };

Then use Base32 to encode uint8_t data[10] whose encode table is

  char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";

After encoding, you will get a 16-char-long string starting with "NAV".

Finally, divide the 16-char-long string to four 4-chars-long blocks and join them with "-" then you will get snKey.

2. Activation Process

  1. Check whether snKey that user inputs is valid.

  2. After user clicks Activate, Navicat will start online activation first. If fails, user can choose offline activation.

  3. Navicat will use the snKey that user inputs and some information collected from user's machine to generate Offline Activation Request Information. Then Navicat will encrypt it by Navicat Activation Public Key and return a Base64-encoded string as Request Code.

  4. In legal way, the Request Code should be sent to Navicat official activation server by a Internet-accessible computer. And Navicat official activation server will return a legal Activation Code.

But now, we use keygen to play the official activation server's role.

  1. According to the Request Code, get "DI" value and "K" value.

  2. Fill Offline Activation Response Information with "K" value, name, organization name, "DI" value and, if need, "T" value.

  3. Encrypt Offline Activation Response Information by Navicat Activation Private Key and you will get 256-byte-long data.

  4. Encode the 256-byte-long data by Base64. The result is Activation Code.

  5. After user input Activation Code, offline activation is done successfully.