HOW_DOES_IT_WORK.zh-CN.md 11 KB

Navicat keygen - 注册机是怎么工作的?

1. 关键词解释.

  • Navicat激活公钥

这是一个2048位的RSA公钥,Navicat使用这个公钥来完成相关激活信息的加密和解密。

这个公钥储存在

  Navicat Premium.app/Contents/Resources/rpk

中,你可以用任何一种文本编辑器打开并查看它。这个公钥的具体内容为:

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

如果您有相应的私钥并乐意公开的话欢迎联系我,我将非常感谢您的慷慨。

注意:

Navicat Premium for Mac 12.0.24 开始,公钥不再存储在

  Navicat Premium.app/Contents/Resources/rpk

中。事实上,公钥放在了Navicat的二进制执行文件

  Navicat Premium.app/Contents/MacOS/Navicat Premium

中,你可以通过搜索"-----BEGIN PUBLIC KEY-----"来找到它。

注意:

Navicat Premium for Mac 12.1.14 开始,公钥仍然以明文的方式储存在二进制可执行文件中。

但是Navicat并不从这个明文中加载公钥。事实上,密钥是从一段0x188字节长的密文中加载的。密文为:

  const uint8_t ciphertext[0x188] = {
      0xfe, 0xfd, 0xfc, 0xf4, 0xfe, 0xd2, 0xf8, 0xf4, 0xf1, 0xd3, 0xde, 0xc7, 0xdf, 0xd3, 0xd0, 0xfd,
      0x8a, 0xc3, 0x85, 0xf4, 0xf6, 0xe9, 0xfc, 0xfc, 0xf2, 0xf5, 0xfa, 0xf5, 0xf6, 0xe9, 0x81, 0xfb,
      0xfe, 0xfd, 0xfc, 0xf4, 0xf4, 0xdf, 0xf2, 0xf9, 0xf2, 0xe5, 0xf0, 0xf7, 0xc0, 0x89, 0xdd, 0xcb,
      0xf5, 0x87, 0xe6, 0xdd, 0xf4, 0xd9, 0xf8, 0xfb, 0xde, 0xf9, 0xcf, 0xc5, 0x8f, 0x80, 0x80, 0xf3,
      0xc2, 0xd0, 0xe2, 0x8f, 0xfa, 0x8a, 0xdd, 0xf3, 0xd7, 0xdc, 0x86, 0xdc, 0xf0, 0x81, 0xc0, 0xea,
      0xd0, 0xd9, 0xf9, 0xd8, 0xda, 0xf2, 0xd0, 0xfd, 0xc3, 0xf6, 0xf3, 0x82, 0xf2, 0x81, 0xef, 0xf2,
      0xe0, 0xf9, 0xf2, 0xd3, 0x8f, 0xd7, 0xe9, 0xfb, 0xca, 0x86, 0xde, 0xfc, 0xf3, 0xd5, 0xdd, 0xf4,
      0xc7, 0x80, 0xf7, 0xd5, 0xf2, 0xc1, 0xde, 0xcc, 0xc0, 0xc7, 0xf0, 0xd0, 0xd0, 0xd1, 0xd7, 0xcc,
      0xd2, 0x81, 0xc1, 0x83, 0xdd, 0xd5, 0x8a, 0x8f, 0x81, 0xe1, 0xf4, 0xd9, 0xf3, 0xd7, 0xca, 0xef,
      0xf9, 0xdf, 0xe1, 0xee, 0xf0, 0xe9, 0xd1, 0xca, 0xf2, 0xe3, 0xf8, 0xf0, 0x83, 0xde, 0xfb, 0xd7,
      0xf1, 0xc4, 0xfa, 0x85, 0xf2, 0xdd, 0xdd, 0xfd, 0x85, 0x86, 0xc7, 0xf9, 0xc4, 0xc9, 0xf4, 0xf8,
      0xd4, 0xd9, 0xe6, 0xd2, 0xf6, 0xc1, 0xc1, 0xf9, 0xe0, 0xe4, 0xf7, 0xe4, 0xfd, 0xf1, 0xf6, 0xfc,
      0xe1, 0x84, 0xe4, 0xd1, 0xed, 0xfe, 0xdb, 0xe8, 0xdd, 0xe1, 0x85, 0xd0, 0xc5, 0xd2, 0x8a, 0x8e,
      0xd5, 0xdd, 0xe3, 0xdb, 0xd0, 0xe1, 0xd0, 0xf6, 0xc6, 0xee, 0xe6, 0xf7, 0xda, 0xf1, 0xdb, 0xc9,
      0x8b, 0xee, 0xcd, 0xdf, 0xff, 0xe8, 0xdd, 0xca, 0x82, 0xdb, 0xf1, 0x82, 0xc3, 0xed, 0xc9, 0xcc,
      0xc0, 0xf2, 0xd6, 0xdf, 0x83, 0xe9, 0xf3, 0xce, 0xea, 0xfa, 0xdf, 0xf8, 0xd9, 0xff, 0xec, 0x88,
      0xe4, 0xe4, 0xfd, 0x80, 0xc5, 0xce, 0xfa, 0xd2, 0xf4, 0xd8, 0x84, 0xff, 0xe5, 0xf3, 0xcb, 0xc2,
      0xfe, 0xc0, 0xc4, 0xfa, 0xde, 0xdd, 0xd5, 0xc9, 0xc5, 0xd5, 0xdf, 0xe3, 0xdd, 0xc1, 0xcb, 0xdd,
      0xfc, 0xf7, 0x83, 0xf8, 0xda, 0xc1, 0xd4, 0xe3, 0xfe, 0xc2, 0xef, 0xf8, 0xf2, 0xea, 0x8a, 0xd2,
      0xc7, 0xf2, 0xf0, 0xc2, 0xfb, 0x89, 0xdc, 0xeb, 0xd1, 0xf7, 0xcc, 0xe2, 0xd1, 0xfc, 0xd4, 0xce,
      0xea, 0xcd, 0xe4, 0x87, 0xe0, 0xcc, 0x8d, 0xf5, 0xc7, 0x85, 0x87, 0xda, 0xcf, 0xde, 0x89, 0xcd,
      0xe5, 0xfd, 0xe7, 0x83, 0xda, 0xdb, 0xfe, 0xf4, 0x84, 0xec, 0xf6, 0xee, 0xfd, 0xea, 0xf1, 0xf5,
      0xf5, 0xfc, 0xe6, 0xd0, 0x86, 0xdf, 0xc3, 0xe2, 0xe4, 0xd5, 0xd7, 0xe4, 0xe4, 0xce, 0xd4, 0xce,
      0x82, 0xda, 0xc7, 0xda, 0x80, 0xcb, 0xee, 0x8c, 0xd0, 0xde, 0xcd, 0xda, 0xdd, 0xcd, 0xcc, 0xeb,
      0xd2, 0xc3, 0xfc, 0xf2, 0xf6, 0xe9, 0xf8, 0xf8
  };

这个密文是采用XOR加密得来,XOR密钥为

  \xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba
  • 请求码

这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 离线激活信息Navicat激活公钥 加密的密文。

  • 离线激活请求信息

这是一个JSON风格的UTF-8字符串。它包含了3个Key:"K""DI""P",分别代表 序列号设备识别码(与你的电脑硬件信息相关)和 平台 (其实就是操作系统类型)。

例如:

  { "K": "xxxxxxxxxxxxxxxx", "P": "Mac 10.13", "DI": "xxxxxxxxxxxxxxxxxxxx" }
  • 激活码

这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 离线激活回复信息Navicat激活私钥 加密的密文。目前我们不知道官方的 Navicat激活私钥,所以我们得替换掉软件里的公钥。

  • 离线激活回复信息

离线激活请求信息 一样,它也是一个JSON风格的UTF-8字符串。但是它包含5个Key,分别为"K""N""O""T""DI".

"K""DI" 的意义与 离线激活请求信息 中的相同,且Value必须与 离线激活请求信息 中的相同。

"N""O""T" 分别代表 注册名组织授权时间

注册名组织 的值类型为UTF-8编码的字符串。授权时间 的值类型可以为字符串或整数(感谢@Wizr在issue #10中的报告)。

和Windows版本Navicat不同的是,"T" 项不可以省略,并且和当前时间的差距必须在-1 ~ +4天之内。

例如:

  {  
    "DI" : "xxxxxxxxxxxxxxxxxxxx",  
    "T" : "1515770827.925012",  
    "K" : "xxxxxxxxxxxxxxxx",  
    "N" : "DoubleLabyrinth",  
    "O" : "Shadow"  
  }
  • 序列号

这是一个被分为了4个部分的字符串,其中每个部分都是4个字符长。

序列号 是通过10个字节的数据来生成的。为了表达方便,我用 uint8_t data[10] 来表示这10个字节。

  1. data[0]data[1] 必须分别为 0x680x2A

    这两个字节为Navicat的标志数。

  2. data[2]data[3]data[4] 可以是任意字节,你想设成什么都行。

  3. data[5]data[6] 是Navicat的语言标志,值如下:

    | 语言类型 | data[5] | data[6] | 发现者 | |------------|:---------:|:---------:|-----------------| | 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] 是Navicat产品ID。(感谢 @dragonflylee@Deltafox79提供的数据)

    |产品名 |Enterprise|Standard|Educational|Essentials| |---------------------|:--------:|:------:|:---------:|:--------:| |Navicat Report Viewer|0x0B | | | | |Navicat Data Modeler | |0x47 |0x4A | | |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. data[8] 的高4位代表 版本号。低4位未知,但可以用来延长激活期限,可取的值有00000001

    例如:

    对于 Navicat 12: 高4位必须是1100,为12的二进制形式。
    对于 Navicat 11: 高4位必须是1011,为11的二进制形式。

  6. data[9] 目前暂未知,但如果你想要 not-for-resale license 的话可以设成0xFD0xFC0xFB

    根据 Navicat 12 for Mac x64 版本残留的符号信息可知:

    • 0xFBNot-For-Resale-30-days license.
    • 0xFCNot-For-Resale-90-days license.
    • 0xFDNot-For-Resale-365-days license.
    • 0xFENot-For-Resale license.
    • 0xFFSite license.

之后Navicat使用 ECB 模式的 DES 算法来加密 data[10] 的后8字节,也就是 data[2]data[9] 的部分。

相应的DES密钥为:

  const uint8_t DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };

之后使用Base32编码 data[10],其中编码表改为:

  // Thanks for discoveries from @Wizr, issue #10
  char EncodeTable[] = "ABCDEFGH8JKLMN9PQRSTUVWXYZ234567";

编码之后你应该会得到一个16字节长的字符串,并且以"NAV"打头。

将16字节的字符串分成4个4字节的小块,然后用"-"连接就可以得到 序列号

2. 激活过程

  1. 检查用户输入的 序列号 是否合法。

  2. 在用户点击了激活按钮之后,Navicat会先尝试在线激活。如果失败,用户可以选择离线激活。

  3. Navicat会使用用户输入的 序列号 以及从用户电脑收集来的信息生成 离线激活请求信息,然后用 Navicat激活公钥 加密,并将密文用Base64编码,最后得到 请求码

  4. 正常流程下,请求码 应该通过可联网的电脑发送给Navicat的官方激活服务器。之后Navicat的官方激活服务器会返回一个合法的 激活码

但现在我们使用注册机来扮演官方激活服务器的角色,只是Navicat软件里的激活公钥得换成自己的公钥:

  1. 根据 请求码, 获得"DI"值和"K"值。

  2. "K"值、用户名、组织名和"DI"值填写 离线激活回复信息

  3. 用自己的2048位RSA私钥加密 离线激活回复信息,你将会得到256字节的密文。

  4. 用Base64编码这256字节的密文,就可以得到 激活码

  5. 在Navicat软件中填入 激活码 即可完成离线激活。