我是否误解了哈希盐是什么?

发布于 2024-08-19 17:03:04 字数 88 浏览 2 评论 0 原文

我正在努力将哈希摘要生成功能添加到我们的代码库中。我想使用字符串作为哈希盐,以便可以将预先知道的密钥/密码短语添加到需要哈希的任何内容之前。我是否误解了这个概念?

I am working on adding hash digest generating functionality to our code base. I wanted to use a String as a hash salt so that a pre-known key/passphrase could be prepended to whatever it was that needed to be hashed. Am I misunderstanding this concept?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

碍人泪离人颜 2024-08-26 17:03:04

盐是添加到加密函数的输入中的随机元素,目的是在每次调用时以不同的方式影响处理和输出。与“密钥”相反,盐并不意味着保密。

一个世纪前,用于加密或身份验证的密码方法是“秘密的”。然后,随着计算机的出现,人们意识到将一种方法完全保密是很困难的,因为这意味着对软件本身保密。定期写入磁盘或体现为某些专用硬件的东西很难保密。因此,研究人员将“方法”分为两个不同的概念:算法(它是公开的,成为软件和硬件)和密钥(算法的参数,存在仅在处理期间位于易失性 RAM 中)。密钥集中了秘密,并且是纯粹的数据。当密钥存储在人类大脑中时,它通常被称为“密码”,因为人类更擅长记住单词而不是位。

后来钥匙本身就被分裂了。事实证明,为了获得适当的加密安全性,我们需要两件事:机密参数和可变参数。基本上,为不同的用途重复使用相同的密钥往往会造成麻烦;它经常泄露信息。在某些情况下(尤其是流密码,也适用于散列密码),它会泄漏太多并导致成功的攻击。因此,经常需要可变性,即每次加密方法运行时都会发生变化。现在的好处是,大多数时候,可变性和秘密不需要合并。也就是说,我们可以将机密变量分开。因此密钥被拆分为:

  • 秘密密钥,通常称为“密钥”;
  • 一个可变元素,通常是随机选择的,根据算法类型称为“盐”或“IV”(作为“初始值”)。

只有密钥需要保密。变量元素需要所有相关方都知道,但它可以是公开的。这是一件幸事,因为共享密钥很困难;用于分发此类秘​​密的系统会发现容纳每次算法运行时都会发生变化的可变部分的成本很高。

在存储散列密码的情况下,上面的解释如下:

  • “重用密钥”意味着两个用户碰巧选择了相同的密码。如果只是对密码进行哈希处理,那么两个用户将获得相同的哈希值,这将显示出来。这里就是泄漏。
  • 同样,如果没有哈希,攻击者可以使用预先计算的表进行快速查找;他还可以并行攻击数千个密码。这仍然使用相同的泄漏,只是以某种方式说明了为什么此泄漏很糟糕。
  • 加盐意味着向哈希函数输入添加一些可变数据。该变量数据就是盐。盐的要点是两个不同的用户应尽可能使用不同的盐。但密码验证者需要能够从密码重新计算相同的哈希值,因此他们必须有权访问盐。

由于验证者必须可以访问盐,但不需要保密,因此通常将盐值与哈希值一起存储。例如,在 Linux 系统上,我可以使用以下命令:

openssl passwd -1 -salt "zap" "blah"

这会使用哈希函数 MD5 计算哈希密码,适合在 /etc/password/etc/shadow 中使用 文件,密码 "blah" 和盐 "zap" (这里,我明确选择盐,但在实际情况下应该随机选择)。输出如下:

$1$zap$t3KZajBWMA7dVxwut6y921

其中美元符号用作分隔符。开头的“1” 标识散列方法(MD5)。盐就在那里,以明文形式表示。最后一部分是哈希函数的输出。

(某处)有关于如何将盐和密码作为散列函数的输入发送的规范(至少在 glibc 源代码中,可能在其他地方)。

编辑:在“登录名和密码”用户身份验证系统中,“登录名”可以充当可接受的盐(两个不同的用户将具有不同的登录名),但这并不能捕获给定的用户更改其密码(新密码是否与旧密码相同都会泄漏)。

A salt is a random element which is added to the input of a cryptographic function, with the goal of impacting the processing and output in a distinct way upon each invocation. The salt, as opposed to a "key", is not meant to be confidential.

One century ago, cryptographic methods for encryption or authentication were "secret". Then, with the advent of computers, people realized that keeping a method completely secret was difficult, because this meant keeping software itself confidential. Something which is regularly written to a disk, or incarnated as some dedicated hardware, has trouble being kept confidential. So the researchers split the "method" into two distinct concepts: the algorithm (which is public and becomes software and hardware) and the key (a parameter to the algorithm, present in volatile RAM only during processing). The key concentrates the secret and is pure data. When the key is stored in the brain of a human being, it is often called a "password" because humans are better at memorizing words than bits.

Then the key itself was split later on. It turned out that, for proper cryptographic security, we needed two things: a confidential parameter, and a variable parameter. Basically, reusing the same key for distinct usages tends to create trouble; it often leaks information. In some cases (especially stream ciphers, but also for hashing passwords), it leaks too much and leads to successful attacks. So there is often a need for variability, something which changes every time the cryptographic method runs. Now the good part is that most of the time, variability and secret need not be merged. That is, we can separate the confidential from the variable. So the key was split into:

  • the secret key, often called "the key";
  • a variable element, usually chosen at random, and called "salt" or "IV" (as "Initial Value") depending on the algorithm type.

Only the key needs to be secret. The variable element needs to be known by all involved parties but it can be public. This is a blessing because sharing a secret key is difficult; systems used to distribute such a secret would find it expensive to accommodate a variable part which changes every time the algorithm runs.

In the context of storing hashed passwords, the explanation above becomes the following:

  • "Reusing the key" means that two users happen to choose the same password. If passwords are simply hashed, then both users will get the same hash value, and this will show. Here is the leakage.
  • Similarly, without a hash, an attacker could use precomputed tables for fast lookup; he could also attack thousands of passwords in parallel. This still uses the same leak, only in a way which demonstrates why this leak is bad.
  • Salting means adding some variable data to the hash function input. That variable data is the salt. The point of the salt is that two distinct users should use, as much as possible, distinct salts. But password verifiers need to be able to recompute the same hash from the password, hence they must have access to the salt.

Since the salt must be accessible to verifiers but needs not be secret, it is customary to store the salt value along with the hash value. For instance, on a Linux system, I may use this command:

openssl passwd -1 -salt "zap" "blah"

This computes a hashed password, with the hash function MD5, suitable for usage in the /etc/password or /etc/shadow file, for the password "blah" and the salt "zap" (here, I choose the salt explicitly, but under practical conditions it should be selected randomly). The output is then:

$1$zap$t3KZajBWMA7dVxwut6y921

in which the dollar signs serve as separators. The initial "1" identifies the hashing method (MD5). The salt is in there, in cleartext notation. The last part is the hash function output.

There is a specification (somewhere) on how the salt and password are sent as input to the hash function (at least in the glibc source code, possibly elsewhere).

Edit: in a "login-and-password" user authentication system, the "login" could act as a passable salt (two distinct users will have distinct logins) but this does not capture the situation of a given user changing his password (whether the new password is identical to an older password will leak).

云之铃。 2024-08-26 17:03:04

您完全理解了这个概念。只要确保预先添加的盐每次都是可重复的。

You are understanding the concept perfectly. Just make sure the prepended salt is repeatable each and every time.

明天过后 2024-08-26 17:03:04

如果我理解正确的话,那么听起来你是对的。该过程的伪代码看起来像这样:

string saltedValue = plainTextValue + saltString;
// or string saltedalue = saltString + plainTextValue;

Hash(saltedValue);

Salt 只是为试图获取您的信息的人们增加了另一层复杂性。

If I'm understanding you correctly, it sounds like you've got it right. The psuedocode for the process looks something like:

string saltedValue = plainTextValue + saltString;
// or string saltedalue = saltString + plainTextValue;

Hash(saltedValue);

The Salt just adds another level of complexity for people trying to get at your information.

吃素的狼 2024-08-26 17:03:04

如果每个加密短语的盐都不同,那就更好了,因为每个盐都需要自己的彩虹表。

And it's even better if the salt is different for each encrypted phrase since each salt requires its own rainbow table.

一指流沙 2024-08-26 17:03:04

值得一提的是,即使每次使用的密码盐应该不同,但您的盐决不应该从密码本身计算出来!此类事情的实际结果是使您的安全性完全失效。

Its worth mentioning that even though the salt should be different for each password usage, your salt should in NO WAY be computed FROM the password itself! This sort of thing has the practical upshot of completely invalidating your security.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文