考虑这个阴影字符串
$y$j9T$PaFEMV0mbpeadmHDv0Lp31$G/LliR3MqgdjEBcFC1E.s/3vlRofsZ0Wn5JyZHXAol5
Run Code Online (Sandbox Code Playgroud)
有4部分
问:
j9T
param 字段中的含义是什么?我见过这个问题;然而,加密密码的格式/etc/shadow
,那里没有解释。
NUL*_*LLx 10
以下是我自己的发现以及我在没有对密码学和所涉及的概念有专业了解的情况下解释它们的方式。
值得注意的是,正如OpenWall GitHub 上的yescrypt
CHANGES
文件所述,关于0.8.1 (2015/10/25) 和 1.0.0 (2018/03/09) 之间所做的更改,yescrypt
有两个签名:
$7$
- 经典scrypt
哈希,不是很紧凑的定长编码$y$
- 原生yescrypt
和经典scrypt
哈希,新的极其紧凑的可变长度编码这种极其紧凑的可变长度编码引入了UNIX StackExchange 答案中倒数第二段末尾所讨论的大部分复杂性,但不是全部复杂性。
对于参数的简单描述,BitcoinWiki Yescrypt 参数部分可能会有所帮助:
范围 | 描述 |
---|---|
password |
密码哈希 |
salt |
使用盐 |
flags |
切换功能的标志 |
N |
增加 N 会增加运行时间和内存使用 |
r |
增加 R 会增加算法操作的块的大小(从而增加内存使用) |
p |
并行系数 |
t |
增加 T 会增加运行时间而不增加内存使用 |
g |
哈希值“升级”的次数,用于加强存储的密码哈希值,而不需要知道原始密码 |
NROM |
结果密钥将依赖的只读存储器 |
DKLen |
导出密钥的长度(输出) |
其中,$7$
哈希仅使用以下内容:
N
- 用1个字节(字符)编码r
- 用5个字节(字符)编码p
- 用5个字节(字符)编码由于$7$
也意味着固定长度编码,每个参数都有预先指定的字节数对其进行编码,并且每个参数都按顺序排列:$7$Nrrrrrppppp$
...。$
让我们将每个字节括在[]
方括号中:$7$[N][r1][r2][r3][r4][r5][p1][p2][p3][p4][p5]$
... $
。此外,这意味着 11 是指定序列中的参数所需的确切字节数(因此它不紧凑)。
另一方面,$y$
哈希值需要三个参数:
flags
- 至少使用 1 个字节(字符)进行编码N
- 至少使用 1 个字节(字符)进行编码r
- 至少使用 1 个字节(字符)进行编码尽管如此,哈希仍然可以通过使用可变长度$y$
编码来使用所有参数。实际上,这意味着每个参数都以自己的大小为前缀#编码在第一个字节中,并以#个字节继续:
$y$[flags_len=#][flags1]
…………[flags#][N_len=#][N1]
[N#][r_len=#][r1]
$
$
为了使事情变得更加复杂,强制参数后面跟着一个可选have
参数。根据 的值have
,yescrypt决定、 、和中的哪些p
(如果有的话)也是所提供数据的一部分。t
g
NROM
有关参数以及在什么情况下使用哪些参数的综合指南,最好查阅OpenWall GitHub 上的yescrypt
PARAMETERS
文件。
参数字段的解码是通过 完成的decode64_uint32()
,它使用一个数组,该数组以当前字节的 ASCII 值与句点字符 (46) 之间的差值为索引,该值是基数:atoi64()
.
atoi64_partial[77] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
64, 64, 64, 64, 64, 64, 64,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
64, 64, 64, 64, 64, 64,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
};
Run Code Online (Sandbox Code Playgroud)
对于每个字段,从第一个字段字节开始yescrypt
执行以下操作:
BitcoinWiki Yescrypt 函数部分中有一些其他进程的伪代码。
让我们从PARAMETERS
上面的文件中举一个例子:
flags = YESCRYPT_DEFAULTS
N = 4096
r = 32
p = 1
t = 0
g = 0
NROM = 0
上述值集被描述为密码散列的标准大且慢(内存使用量 16 MiB,性能如 bcrypt 成本 2^8 - 延迟 10-30 毫秒,吞吐量在 16 核服务器上每秒 1000+)用户认证,无ROM。
$y$
是签名。
flags = YESCRYPT_DEFAULT = 182 = 0xB6 = j
在yescrypt
可变长度编码中。
这里,flags
应该解码为YESCRYPT_DEFAULT
,这相当于YESCRYPT_RW_DEFAULTS
,定义为(YESCRYPT_RW | YESCRYPT_ROUNDS_6 | YESCRYPT_GATHER_4 | YESCRYPT_SIMPLE_2 | YESCRYPT_SBOX_12K)
:
YESCRYPT_RW = 0x002
YESCRYPT_ROUNDS_6 = 0x004
YESCRYPT_GATHER_4 = 0x010
YESCRYPT_SIMPLE_2 = 0x020
YESCRYPT_SBOX_12K = 0x080
执行逻辑OR
运算,yescrypt
得出最终数字并对其进行编码。
N = 4096 = 0x1000 = 9
在yescrypt
可变长度编码中。事实上,N = 2解码_N_字段。
r = 32 = 0x20 = T
在yescrypt
可变长度编码中。
$
此时表明yescript
没有指定可选参数。
最后,加入盐。理论上它是任意长度的。但是,盐的长度必须是 4 的幂。
$y$j9T$SALT$
以下是一些有效但不安全的示例,在完成上述描述后可能会在视觉上有所帮助:
$7$9/..../..../$SALTS$
$y$./.$SALT$
$y$8/.$SALT$