-
Notifications
You must be signed in to change notification settings - Fork 2.4k
WinRAR 使用了基于 ECC 的签名算法来生成 rarreg.key
文件,其使用的签名算法是中国 SM2 数字签名算法的变体。与各种标准 ECDSA 不同的是,WinRAR 使用的椭圆曲线是一个基于复合域 上的曲线。
基域 采用标准基(多项式基)来表达,采用的不可约多项式为:
各项系数全部位于 。设基域的标准基为:
则位于基域 上的元素
可以用如下方式表达:
复合域 的不可约多项式为:
各项系数全部位于 。设复合域的标准基为:
则位于复合域 上的元素
可以用如下方式表达:
为了方便表述我们用255比特的大数 来表示位于复合域
上的元素
。它们的对应关系为:
曲线方程为:
基点 为:
基点 的阶
为:
设长度为 的消息为:
则消息 的SHA1值为:
其中 为SHA1算法输出时的5个状态值;将这5个状态值按照大端字节序依次输出,即为的SHA1哈希值
。
WinRAR在做完SHA1计算后,采用大数 作为ECC签名时消息的哈希:
设私钥为 ,公钥为
,即:
消息哈希为 ,则签名
为:
-
生成随机数
,满足
。
-
计算
其中
表示取
的X坐标,同时将X坐标从
转换为大数。
若
或者
则回到步骤1。
-
计算
若
则回到步骤1。
-
输出
。
该算法会利用长度为 的数据
来生成私钥 。
-
设6个32位整数为
,则有
-
令
。
-
如果
则计算
的SHA1值,并将状态值
赋值给
:
否则,即
时,令:
-
把
作为计数器,自增1。
计算SHA1值:
取
的低16位并记为
。
-
步骤4再重复14次。
-
重复执行完后会得到
,则输出私钥
WinRAR的私钥 为:
该私钥是通过算法5生成的,其中数据 的长度为0。
公钥 为:
授权文件的生成需要两个参数:
-
用户名的ANSI字符串,不包括null-terminator;记为
-
授权类型的ANSI字符串,不包括null-terminator;记为
rarreg.key
的生成算法如下:
-
使用用户名
通过算法5计算出私钥
以及公钥
,并将公钥
按照SM2压缩公钥格式以Hex字符串(ASCII编码)的形式输出。得到的Hex字符串记为临时值
。
的长度应该为64;若长度不足,则在前面补字符
'0'
,直到长度为64。 -
令字符串
为
-
使用
通过算法5计算出私钥
以及公钥
,并将公钥
按照SM2压缩公钥格式以Hex字符串(ASCII编码)的形式输出。得到的Hex字符串记为
。
的长度应该为64;若长度不足,则在前面补字符
'0'
,直到长度为64。 -
令字符串
为
-
对授权类型
使用算法4得到签名
,其中私钥见第6节。
要求
和
的长度都不得超过240比特,否则重复该步骤。
-
将
和
以16进制形式输出(无
"0x"
前缀),分别记为和
。
若长度不满60,则在前面补字符
'0'
,直到长度为60。 -
令字符串
为
-
令字符串
为
对
使用算法4得到签名
,其中私钥见第6节。
要求
和
的长度都不得超过240比特,否则重复该步骤。
-
将
和
以16进制形式输出(无
"0x"
前缀),分别记为和
。
若长度不满60,则在前面补字符
'0'
,直到长度为60。 -
令字符串
为
-
对
计算CRC32值,最终校验和为CRC32值的反。将校验和以10进制形式输出,若长度不满10,则在前面补字符
'0'
,直到长度为10,记为。
-
令字符串
为
-
格式化输出。
-
固定文件头
"RAR registration data"
,占一行。 -
用户名,占一行。
-
授权类型,占一行。
-
UID,占一行:
-
将
按照每行54个字符输出。
-