使用 SHA-256 和 SHA-512 的 Unix crypt 中的 SALT 字符串的术语“简单字符串”是什么意思?

信息安全 哈希 Unix 沙2
2021-08-14 00:55:07

使用 SHA-256 和 SHA-512的 Unix crypt 中,作者 Ulrich Drepper 介绍了SALT 字符串如下(由我强调):

对于基于 SHA 的方法,SALT 字符串可以是最多使用 16 个字符的简单字符串

将此字符串称为简单字符串的理由是什么?这是什么意思?后果是什么?例如,我对提供 16 个 NUL 字节字符串的边缘情况特别感兴趣。

2个回答

该文本的意思是“简单”,与旧的基于 DES 的旧传统 DEScrypt()中使用的相反,其中 salt 是 12 位值,表示为受限集中的两个字符。Ulrich Drepper 想说他的创作不那么挑剔,可以将最多 16 个字节的任何序列作为盐。

尽管散列函数本身可以处理任何字节(包括零,这对于散列函数而言并不特殊),但您链接到的文本中显示的 C 代码使用基于字符串的 API:

char *
sha256_crypt (const char *key, const char *salt)

即盐将在第一个零值字节之前停止,或在第 16 个字节之后停止,以先到者为准。此外,salt 的值将是生成的输出字符串的一部分,因此 salt 最好包含可打印的 ASCII 字符并且不包括'$'符号,因为这是在该字符串中用作分隔符的内容。

为该函数生成“正确的盐字符串”的一种简单方法是生成恰好 12 个随机字节的序列(取自良好的 PRNG,即/dev/urandom),并使用Base64对它们进行编码。这将产生 16 个随机字符,在一个包含字母(大写和小写)、数字'+''/'-- 的字母表中,仅此而已,特别是没有'$'和没有麻烦的控制字符。盐仍然有 96 位熵,使得盐重用相当不可能(所以一切都会好起来的)。

在这种情况下,一个简单的字符串是 C 中的任何字符数组,例如:char[]. 该代码正在执行 strlen() ,因此它以空值终止。盐应该是加密随机数。