这是一个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个字节。
data[0] 和 data[1] 必须分别为 0x68
和 0x2A
。
这两个字节为Navicat的标志数。
data[2]、data[3] 和 data[4] 可以是任意字节,你想设成什么都行。
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 |
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 | |
data[8] 的高4位代表 版本号。低4位未知,但可以用来延长激活期限,可取的值有0000
和0001
。
例如:
对于 Navicat 12: 高4位必须是1100
,为12
的二进制形式。
对于 Navicat 11: 高4位必须是1011
,为11
的二进制形式。
data[9] 目前暂未知,但如果你想要 not-for-resale license 的话可以设成0xFD
、0xFC
或0xFB
。
根据 Navicat 12 for Mac x64 版本残留的符号信息可知:
0xFB
是 Not-For-Resale-30-days license.0xFC
是 Not-For-Resale-90-days license.0xFD
是 Not-For-Resale-365-days license.0xFE
是 Not-For-Resale license.0xFF
是 Site 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字节的小块,然后用"-"
连接就可以得到 序列号。
检查用户输入的 序列号 是否合法。
在用户点击了激活
按钮之后,Navicat会先尝试在线激活。如果失败,用户可以选择离线激活。
Navicat会使用用户输入的 序列号 以及从用户电脑收集来的信息生成 离线激活请求信息,然后用 Navicat激活公钥 加密,并将密文用Base64编码,最后得到 请求码。
正常流程下,请求码 应该通过可联网的电脑发送给Navicat的官方激活服务器。之后Navicat的官方激活服务器会返回一个合法的 激活码。
但现在我们使用注册机来扮演官方激活服务器的角色,只是Navicat软件里的激活公钥得换成自己的公钥:
根据 请求码, 获得"DI"
值和"K"
值。
用"K"
值、用户名、组织名和"DI"
值填写 离线激活回复信息。
用自己的2048位RSA私钥加密 离线激活回复信息,你将会得到256字节的密文。
用Base64编码这256字节的密文,就可以得到 激活码。
在Navicat软件中填入 激活码 即可完成离线激活。