实际上,您正在以相反的方式处理它。
确实,这样做hash(salt + password)
可以让您预先计算盐(但请参阅下面的注释),并且只对所有这些试验的每个密码候选者进行哈希处理。如果您根本不使用盐,您将承担相同的成本。
但是,salt 的目标不是让破解单个哈希变得更加困难,而是确保不同用户的哈希即使选择相同的密码也是不同的,因此破解工作不能应用于多个用户。
假设您在他们使用 MD5 哈希的地方转储了一个 PayPal 数据库哈希。您要检查密码“paypal”、“PayPal”、“PayPal123”...
如果他们使用 MD5(密码),您可以简单地对其中任何一个进行哈希处理,并找出是否有人在使用这种弱密码。
如果他们使用 MD5(盐 + 密码),您可以为每个人预先计算部分 MD5(盐),但仍然需要为每个用户散列每个候选密码。
如果他们使用 MD5(密码 + salt),您可以为每个候选密码预先计算部分 MD5(密码),然后为每个用户应用他们的 salt。
#1显然是这里最糟糕的。您可以根据密码和盐的不同长度以及用户数量在#2和#3之间争论,但我认为#2更可取。仅基于长度,密码的强制最小长度可能高于盐大小。但我怀疑#3 构造也可能存在其他弱点。
这是一个显着的优势吗?
并不真地。
首先,许多散列函数在块中工作,小于块大小的值的预计算只是存储“预计算字节”的副本。在 99% 的情况下,盐和密码的长度都会比块大小短,因此实际上不会执行真正的预计算。您需要在那里使用非常长的字符串才能使用。
此外,任何现代密码哈希函数都将至少使用多次迭代,如果不使用更高级的方法来使暴力破解变得昂贵,并且您的优化仅适用于初始迭代。
在任何情况下,不是简单地将盐和密码连接起来,最安全的组合它们的方法是对它们进行HMAC,从而以更好的方式混合它们。