scrypt输出的最大长度是多少?

13

我想在数据库中保存一个经过scrypt散列的密码。我可以期望最大长度是多少?

答案: scrypt散列后的密码长度不固定,但通常不超过64个字符。
2个回答

11
根据https://github.com/wg/scrypt,输出格式是$s0$params$salt$key,其中:
  • s0表示版本0格式,具有128位盐和256位派生密钥。
  • params是一个32位十六进制整数,包含log2(N)(16位)、r(8位)和p(8位)。
  • salt是base64编码的盐。
  • key是base64编码的派生密钥。
根据https://dev59.com/S2Yr5IYBdhLWcg3wy9SA#13378842,base64编码字符串的长度为4*ceil(n/3),其中n表示要编码的字节数。
让我们来分解一下:
  • 美元符号占用4个字符。
  • 版本号占用2个字符。
  • 每个十六进制字符表示4位(log2(16)=4),因此params字段占用(32位/4位)= 8个字符。
  • 128位盐等于16个字节。 base64编码格式占用(4 * ceil(16 / 3)) = 24个字符。
  • 256位派生密钥等于32个字节。 base64编码格式占用(4 * ceil(32 / 3)) = 44个字符。
将所有这些组合在一起,我们得到:4 + 2 + 8 + 24 + 44 = 82个字符

1
需要注意的是,使用scrypt进行密码存储并没有标准。存在不同的编码格式、不同的盐长度和不同的派生字节密码长度。但世界似乎正在向wg-scrypt格式靠拢。 - Ian Boyd
不确定为什么WG的scrypt加密格式允许log2(N)的值为16位数字。实现使用int表示N,因此log2(N)的最大实际值为31(0x1F)。即使使用long,也不需要额外的数字。该实现使用Java的toString将参数转换为十六进制字符串,没有填充,并且实际上无法使用规范允许的8个字符。参数的实际最大值为6个字符,因此完整字符串的最大值为80。 - Rand
@Rand 你说得对。实现特定的答案是80个字符,但我宁愿按照规范中规定的最大限制出错(以防实现随时间改变)。 - Gili
@Gili 当然,您对规范的理解是完全正确的。但这不仅仅是关于intlong之间的区别。0x100意味着N等于2^256,也就是1x10^77!即使算法被实现为执行那么多次迭代,也不可能做到。我的真正意思是,对于log2(N)来说,16位没有任何意义。这似乎是规范中的一个错误。 - Rand
@Rand 的原因是因为他们正在使用32位的DWORD。8位用于“r”,8位用于“p”。您还剩下16位:将其用于回合数因子。为什么要刻意构造 0x00nnrrpp,当您可以直接使用 0xnnnnrrpp - Ian Boyd
显示剩余3条评论

2
在Colin Percival的实现中,tarsnap scrypt头部是96字节。它包括:
  • 6字节'scrypt'
  • 10字节N、r、p参数
  • 32字节盐
  • 16字节0-47字节的SHA256校验和
  • 32字节0-63字节的HMAC哈希(使用scrypt哈希作为密钥)
这也是node-scrypt使用的格式。在stackexchange上有一个关于校验和和HMAC哈希背后原理的解释。
作为一个base64编码的字符串,这个长度是128个字符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接