Skip to content

Latest commit

 

History

History
330 lines (214 loc) · 19.6 KB

README.HOW_DOES_IT_WORK.zh-CN.md

File metadata and controls

330 lines (214 loc) · 19.6 KB

"rarreg.key"是如何生成的?

WinRAR 使用了基于 ECC 的签名算法来生成 rarreg.key 文件,其使用的签名算法是中国 SM2 数字签名算法的变体。与各种标准 ECDSA 不同的是,WinRAR 使用的椭圆曲线是一个基于复合域 GF2p15p17-inlined GF2p15p17-inlined 上的曲线。

1. 复合域 GF2p15p17-inlined GF2p15p17-inlined

基域 GF2p15-inlinedGF2p15-inlined 采用标准基(多项式基)来表达,采用的不可约多项式为:

各项系数全部位于 GF2-inlinedGF2-inlined。设基域的标准基为:

则位于基域 GF2p15-inlinedGF2p15-inlined 上的元素 AA 可以用如下方式表达:


复合域 GF2p15p17-inlined GF2p15p17-inlined 的不可约多项式为:

各项系数全部位于 GF2p15-inlinedGF2p15-inlined。设复合域的标准基为:

则位于复合域 GF2p15p17-inlined GF2p15p17-inlined 上的元素 BB 可以用如下方式表达:


为了方便表述我们用255比特的大数 DD 来表示位于复合域 GF2p15p17-inlined GF2p15p17-inlined 上的元素 BB。它们的对应关系为:

2. 复合域 GF2p15p17-inlined GF2p15p17-inlined 上的椭圆曲线

曲线方程为:

基点 GG 为:

基点 GG 的阶 nn 为:

3. 消息哈希算法

设长度为 ll 的消息为:

则消息 MM 的 SHA1 值为:

其中 s0,4s0,4 为 SHA1 算法输出时的5个状态值;将这5个状态值按照大端字节序依次输出,即为的 SHA1 哈希值 SHA1MSHA1M

WinRAR 在做完 SHA1 计算后,采用大数 hh 作为 ECC 签名时消息的哈希:

4. ECC签名算法

设私钥为 kk,公钥为 PP,即:

消息哈希为 hh,则签名 (r,s)(r,s) 为:

  1. 生成随机数 RndRnd,满足 RNDRND

  2. 计算 rr

    其中 RNDGxRNDGx 表示取 RNDGRNDG 的 X 坐标,同时将 X 坐标从 GF2p15p17-inlined GF2p15p17-inlined 转换为大数。

    r=0r=0 或者 rRndrRnd 则回到步骤1。

  3. 计算 ss

    s=0s=0 则回到步骤1。

  4. 输出 (r,s)(r,s)

5. WinRAR的私钥生成算法

该算法会利用长度为 ll 的数据

来生成私钥 kk

  1. 设6个32位整数为 g0-5g0-5,则有

  2. g0=0g0=0

  3. 如果 l!=0l!=0 则计算 TT 的 SHA1 值,并将状态值 SiSi 赋值给 gi+1gi+1

    否则,即 l=0l=0 时,令:

  4. g0g0 作为计数器,自增1。

    计算 SHA1 值:

    S0S0 的低16位并记为 Kg0Kg0

  5. 步骤4再重复14次。

  6. 重复执行完后会得到 k1-15k1-15,则输出私钥

6. WinRAR的公钥和私钥

WinRAR 的私钥 kk 为:

该私钥是通过算法5生成的,其中数据 TT 的长度为0。

公钥 PP 为:

7. 授权文件"rarreg.key"的生成

授权文件的生成需要两个参数:

  1. 用户名的 ANSI 字符串,不包括 null-terminator;记为

  2. 授权类型的 ANSI 字符串,不包括 null-terminator;记为

rarreg.key 的生成算法如下:

  1. 使用用户名 UU 通过算法5计算出私钥 kuku 以及公钥 pupu,并将公钥 pupu 按照 SM2 压缩公钥格式以 Hex 字符串(ASCII编码)的形式输出。得到的 Hex 字符串记为临时值 TempTemp

    TempTemp 的长度应该为64;若长度不足,则在前面补字符 '0',直到长度为64。

  2. 令字符串 Data3Data3

  3. 使用 Data3Data3 通过算法5计算出私钥 kdata3kdata3 以及公钥 pdata3pdata3,并将公钥 pdata3pdata3 按照 SM2 压缩公钥格式以 Hex 字符串(ASCII编码)的形式输出。得到的 Hex 字符串记为 Data0Data0

    Data0Data0 的长度应该为64;若长度不足,则在前面补字符 '0',直到长度为64。

  4. 令字符串 UIDUID

  5. 对授权类型 LL 使用算法4得到签名 (rl,sl)(rl,sl),其中私钥见第6节。

    要求 rlrlslsl 的长度都不得超过240比特,否则重复该步骤。

  6. rlrlslsl 以16进制形式输出(无 "0x" 前缀),分别记为 SZrlSZrlSZslSZsl

    若长度不满60,则在前面补字符 '0',直到长度为60。

  7. 令字符串 Data1Data1

  8. 令字符串 TempTemp

    TempTemp 使用算法4得到签名 (rTemp,sTemp)(rTemp,sTemp),其中私钥见第6节。

    要求 rTemprTempsTempsTemp 的长度都不得超过240比特,否则重复该步骤。

  9. rTemprTempsTempsTemp 以16进制形式输出(无 "0x" 前缀),分别记为 SZrTempSZrTempSZsTempSZsTemp

    若长度不满60,则在前面补字符 '0',直到长度为60。

  10. 令字符串 Data2Data2

计算 CRC32 值,最终校验和为 CRC32 值的反。将校验和以10进制形式输出,若长度不满10,则在前面补字符 '0',直到长度为10,记为 SZchecksumSZchecksum

  1. 令字符串 DataData

  2. 格式化输出。

    • 固定文件头 "RAR registration data",占一行。

    • 用户名,占一行。

    • 授权类型,占一行。

    • UID,占一行:

    • DataData 按照每行54个字符输出。