README.zh-CN.md 17 KB

Tuxera NTFS Keygen

1. Tuxera NTFS是什么

Tuxera NTFS是个可用于内部和外部存储、经过性能优化,具备容错性和完全兼容性的文件系统解决方案。Tuxera NTFS已经在市场上一些最新的高端电视、电视机顶盒、智能手机、平板电脑、路由器、网络附属存储和其他设备上使用。Tuxera NTFS目前适用于安卓和其他Linux平台、还有QNX、WinCE Series 40、Nucleus RTOS和 VxWorks等。Tuxera同时也适用于许多构架,如ARM、MIPS、PowerPC、SuperH和x86等。

来自 百度百科

2. 激活密钥是如何生成的?

在Tuxera NTFS中有两类激活密钥,它们分别是

Key Type Key Length Format
Long Product Key 34 chars xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxx
Short Product Key 23 chars xxxxx-xxxxx-xxxxx-xxxxx

Format列中的x字符代表的是下面编码表中的字符:

// defined in CustomBase32Encode function, helper.c file.
const char SubstitutionTable[33] = "0123456789ACDEFGHJKLMNPQRTUVWXYZ";

其中\0字符并不包含在其中

2.1 长激活密钥是如何生成的?

Tuxera NTFS是使用 ECC (Elliptic-curve Cryptography) 来生成长激活密钥的。

其中用到的曲线为secp112r1,是基于有限域的曲线,方程为

其中

使用的基点

基点的阶为

Tuxera NTFS将官方ECC公钥写在了如下几个文件中:

No. Path
1 /Library/PreferencePanes/Tuxera\ NTFS.prefPane/Contents/MacOS/Tuxera\ NTFS
2 /Library/PreferencePanes/Tuxera\ NTFS.prefPane/Contents/Resources/WriteActivationData
3 /Library/PreferencePanes/Tuxera\ NTFS.prefPane/Contents/Resources/WriteActivationDataTiger
4 /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/ntfsck
5 /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/tuxera_ntfs
6 /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/ntfsck
7 /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/tuxera_ntfs

公钥具体的值为

目前我并不知道对应的私钥 是什么。如果你知道请告诉我,我将非常感谢你的慷慨。

以下将说明长激活密钥是如何生成的:

  1. 生成一个大数 ,其中 必须满足

  2. 计算

  3. 准备好一个buffer uint8_t bin_rG[2][14]。将大数 按照 大端字节序 分别写入到bin_rG[0]bin_rG[1]中。如果大数没有14个字节,则在高位补“0”字节即可。

  4. 准备好一个buffer uint8_t Hash[5]。用argon2_hash函数计算bin_rG的哈希,这个函数的定义可在argon2中找到。

     argon2_hash(1,
                 1 << 16,
                 1,
                 bin_rG,
                 sizeof(bin_rG),
                 salt,
                 sizeof(salt),
                 Hash,
                 sizeof(Hash),
                 NULL,
                 0,
                 Argon2_d,
                 ARGON2_VERSION_13);
    

    其中salt

     const uint8_t salt[16] = {
         0xa1, 0x38, 0x11, 0x98, 0x12, 0x2f, 0x28, 0xee,
         0x2c, 0x3a, 0xa0, 0x57, 0xbd, 0xcf, 0x2d, 0x83
     };
    

    计算完成后,清除Hash[4]的低两位。换句话说执行Hash[4] &= 0xFC;

  5. Hash(5字节)按 大端字节序 转化为一个大数

  6. 准备好一个buffer uint8_t bin_s[14]。计算

    并将按照 大端字节序 写入到bin_s中。同样如果大数不满14字节,则在高位补“0”字节。

  7. bin_s(14字节)和Hash(5字节)拼接,则会得到uint8_t key_data[14 + 5],其中key_data的前14字节为bin_s

  8. 使用变种Base32编码方式编码key_data,然后你可以得到prekey_str字符串(包含31个字符)。变种Base32和标准Base32的区别在于:

    1. 在变种Base32中,代换表为0123456789ACDEFGHJKLMNPQRTUVWXYZ;而在标准Base32中,代换表为ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

    2. 当5比特长的编码单元跨过了某个字节时,交换编码单元中在该字节和下一字节的两个部分。

      例如:

      如果有两字节的待编码数据——10111010 11110100——那么在变种Base32中编码单元为10111 11010 11010 00000,而在标准Base32中编码单元为10111 01011 11010 00000;即标准Base32中01011编码单元的两部分——01011——在变种Base32中交换了,因为该编码单元跨过了两个字节。

    3. 在变种Base32中,没有=填充字符。

  9. prekey_str中,最后一个字符肯定是'0',因为Hash[4]的低两位被清空了。移除掉这个字符,那么prekey_str的长度就变为30个字符了。

  10. prekey_str倒序。然后按照每6个字符分块,总共分成5块。将这个5块用英文连字符'-'连接就可以得到长激活密钥。

2.2 短激活密钥是如何生成的?

短激活密钥是由20个整数生成的,每个整数是5位长。为了表达方便,我用uint8_t data[20]来表示这20个整数。

短激活密钥有两种格式:

Key Type 1 2
data[0] x0x0x xxx10
data[1] 10xx0 1xx1x
data[2] x10xx 0xx1x
data[3] 0xxx0
data[4] xx01x 11xxx
data[5] xxx10 1xx1x
data[6] xx10x xx1x1
data[7] xx0x1 xx01x
data[8] x1xxx x00xx
data[9] 1x1xx xx1x1
data[10] xxxx1 1x1xx
data[11] xx11x x0xx0
data[12] x01xx
data[13] x0xx1 x0xx0
data[14] x00xx 00xxx
data[15] 10xxx 1xx0x
data[16] xx0x1 x0x1x
data[17] 101xx xxx01
data[18] xxx0x x11xx
data[19] 10xx1 x10xx

最后两列中的x表示相应的比特可以是01。其他的比特必须如表中所示。

Key Type 1中的data[12]和Key Type 2中的data[3]是校验和。它们必须是其他19个整数的和在模32后的值。

使用下列代换表代换uint8_t data[20]

const char SubstitutionTable[33] = "0123456789ACDEFGHJKLMNPQRTUVWXYZ";

然后你就会得到prekey_str。将prekey_str倒序,并按照每5字符分成4块,然后将这个4块用英文连字符'-'连接就可以得到短激活密钥。

然而一个随机生成的短激活密钥是不能激活Tuxera NTFS的。因为Tuxera已经将所有有效短激活密钥的哈希存在了它们的二进制发布文件中。当且仅当一个短激活密钥的哈希匹配二进制发布文件中众多哈希的其中一个才会被认为是有效的密钥。

从目前的二进制发布文件中来看,Tuxera似乎有150388个有效短激活密钥。我已经从/Library/PreferencePanes/Tuxera\ NTFS.prefPane/Contents/MacOS/Tuxera\ NTFS文件中提取出来了,你可以在code/key_hashes.c文件中看到。

以下将说明短激活密钥的哈希是怎么被计算的:

  1. 一个短激活密钥是23字符长,在其最后添加\n\0两个字符,你将得到25字符长的数据。将之称为uint8_t buf[25]

  2. 使用argon2_hash计算buf的哈希,然后你将得到uint8_t Hash[6]

     argon2_hash(1,
                 1 << 16,
                 1,
                 buf,
                 sizeof(buf),
                 salt,
                 sizeof(salt),
                 Hash,
                 sizeof(Hash),
                 NULL,
                 0,
                 Argon2_d,
                 ARGON2_VERSION_13);
    

    其中salt

     const uint8_t salt[16] = {
         0x06, 0x9c, 0x5e, 0xf4, 0x90, 0x67, 0x39, 0x4c,
         0x7b, 0x61, 0xa7, 0xee, 0x36, 0x97, 0xc6, 0x02
     };
    
  3. 得到的uint8_t Hash[6]就是相应短激活密钥的哈希。

3. 激活密钥是如何被验证的?

3.1 长激活密钥是如何被验证的?

  1. 将长激活密钥解码成19字节长的key_data

  2. key_data的前14字节和后5字节按照 大端字节序 转化成大数

  3. 计算 并将结果按照 大端字节序 写入到uint8_t bin_R[2][14]中,同样若大数不满足14字节则在高位补“0”字节。

  4. 使用argon2_hash函数计算bin_R的哈希uint8_t Hash[5]

  5. 检查Hash是否与key_data的后5字节相同。如果相同则长激活密钥有效,反之无效。

为什么?因为如果长激活密钥是有效的,则必有

所以key_data的后5字节必然与Hash相同:这是长激活密钥有效的必要条件。如果不等,则长激活密钥必然不是合法的激活密钥。

3.2 短激活密钥是如何被验证的?

  1. 将短激活密钥解码成uint8_t data[20]

  2. 检查uint8_t data[20]是否符合Key Type 1或Key Type 2的格式。如果都不符合,则该短激活密钥无效。

  3. 以下短激活密钥被显式封禁:

     N0P1N-0N267-Z9TWU-24CP1    // it may be development-used only
     J0M1H-37VYL-YEVNK-VFVM5    // a widely used leaked key
     9DTQN-166PM-XLUEY-VTCZF    // a widely used leaked key
    

    如果短激活密钥为上述其中一个密钥,则为无效密钥。

  4. 计算短激活密钥的哈希,检查是否为二进制发布文件中众多哈希中的一个。如果是则为有效密钥,否则为无效密钥。

4. 如何编译?

  1. 请确保你有opensslargon2。你可以通过Homebrew安装它们。

     $ brew install openssl
     $ brew install argon2
    
  2. 如果要编译patcher,在控制台中:

     $ cd code
     $ make patcher
    

    之后你会得到TuxeraNTFS-patcher

    如果要编译keygen,在控制台中:

     $ cd code
     $ make keygen
    

    之后你会得到TuxeraNTFS-keygen

    如果要清理,则

     $ cd code
     $ make clean
    

5. 如何使用?

上次测试时间:2018-07-13

上次测试版本:2018 (released 2018-01-25) 你可以从这里下载。

  1. 编译patcher和keygen。

  2. 使用TuxeraNTFS-patcher给Tuxera NTFS打个补丁。在控制台中:

     $ sudo ./TuxeraNTFS-patcher
    

    例如:

     $ sudo ./TuxeraNTFS-patcher
     Password:
     -----secp112r1 Private Key-----
     Bin: 42 EE 5D 2C CD 53 0A 06 43 B9 9A 9E 29 B0
    
     -----secp112r1 Public Key-----
     Bin: X = C3 15 26 EC 75 DE AA 90 4C 70 7B 09 2B EC
     Bin: Y = 68 49 70 AA 04 3D 9F B3 DF 42 63 3D 55 FF
    
     Write private key to tuxera_key.bin successfully.
    
     Patching...
     Target file: /Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/MacOS/Tuxera NTFS
     Open file successfully!
     File size: 3669616 byte(s).
     Map file successfully!
     offset = 0x000000000002ec2a, writing data.....Patch is done.
     offset = 0x000000000014f05e, writing data.....Patch is done.
     offset = 0x0000000000284c40, writing data.....Patch is done.
     Modified: 3
    
     Target file: /Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/Resources/WriteActivationData
     Open file successfully!
     File size: 3180416 byte(s).
     Map file successfully!
     offset = 0x000000000002366e, writing data.....Patch is done.
     offset = 0x000000000011eae6, writing data.....Patch is done.
     offset = 0x0000000000226c74, writing data.....Patch is done.
     Modified: 3
    
     Target file: /Library/PreferencePanes/Tuxera NTFS.prefPane/Contents/Resources/WriteActivationDataTiger
     Open file successfully!
     File size: 2132524 byte(s).
     Map file successfully!
     offset = 0x0000000000023c6b, writing data.....Patch is done.
     offset = 0x0000000000126c84, writing data.....Patch is done.
     Modified: 2
    
     Target file: /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/ntfsck
     Open file successfully!
     File size: 3135728 byte(s).
     Map file successfully!
     offset = 0x0000000000099d07, writing data.....Patch is done.
     offset = 0x000000000021bd4c, writing data.....Patch is done.
     Modified: 2
    
     Target file: /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.4/tuxera_ntfs
     Open file successfully!
     File size: 3005576 byte(s).
     Map file successfully!
     offset = 0x000000000008a747, writing data.....Patch is done.
     offset = 0x00000000001fc754, writing data.....Patch is done.
     Modified: 2
    
     Target file: /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/ntfsck
     Open file successfully!
     File size: 6195032 byte(s).
     Map file successfully!
     offset = 0x0000000000098bc2, writing data.....Patch is done.
     offset = 0x000000000021d890, writing data.....Patch is done.
     offset = 0x0000000000379f0a, writing data.....Patch is done.
     offset = 0x00000000005057a0, writing data.....Patch is done.
     Modified: 4
    
     Target file: /Library/Filesystems/tuxera_ntfs.fs/Contents/Resources/Support/10.5/tuxera_ntfs
     Open file successfully!
     File size: 5958616 byte(s).
     Map file successfully!
     offset = 0x0000000000089382, writing data.....Patch is done.
     offset = 0x00000000001fe27c, writing data.....Patch is done.
     offset = 0x000000000034ec42, writing data.....Patch is done.
     offset = 0x00000000004cc178, writing data.....Patch is done.
     Modified: 4
    

    你会在当前目录下得到tuxera_key.bin文件。

  3. 对Tuxera NTFS重新进行代码签名。因为我们对tuxera_ntfs.fsTuxera NTFS.prefPane打了补丁,所以它们原先的代码签名已经失效。我们必须对它们进行重签名。在控制台中:

     $ sudo codesign -f -s "your code-sign certificate name" /Library/Filesystems/tuxera_ntfs.fs
     $ sudo codesign -f -s "your code-sign certificate name" /Library/PreferencePanes/Tuxera\ NTFS.prefPane
    

    注意: "your code-sign certificate name" 应该是你代码签名证书的名字,它应该显示在你的Keychain.app中。

  4. 运行TuxeraNTFS-keygen来生成激活密钥。在控制台中:

     $ ./TuxeraNTFS-keygen ./tuxera_key.bin
    

    Example:

     $ ./TuxeraNTFS-keygen ./tuxera_key.bin
     -----secp112r1 Private Key-----
     Bin: 42 EE 5D 2C CD 53 0A 06 43 B9 9A 9E 29 B0
    
     -----secp112r1 Public Key-----
     Bin: X = C3 15 26 EC 75 DE AA 90 4C 70 7B 09 2B EC
     Bin: Y = 68 49 70 AA 04 3D 9F B3 DF 42 63 3D 55 FF
    
     Long product key: 4KPGHH-147M3Q-UHN3M2-C4DYAN-ENACL0
    
  5. 现在你可以看到激活密钥了。用它激活Tuxera NTFS即可。