openssl_digest vs hash vs hash_hmac?盐与盐的区别HMAC?区别、vs、openssl_digest、hash

2023-09-06 22:38:26 作者:谢谢妳光临峩的心

我想使用 SHA512 来存储密码.为此,我应该使用 openssl_digesthashhash_hmac 中的哪一个?为什么?

I want to use SHA512 to store passwords. To do that, which of openssl_digest, hash and hash_hmac should I use and why?

SALT & 有什么区别?HMAC?

What is the difference between SALT & HMAC?

我刚刚读到 HMAC 是建立在哈希函数之上的.

I just read that HMAC is built on top of hash function.

那么 SHA512+SALT+HMAC 真的有必要还是 SHA512+SALTSHA512+HMAC?

So is SHA512+SALT+HMAC really necessary or SHA512+SALT or SHA512+HMAC?

推荐答案

所以,首先,让我们弄清楚一件事.openssl_digest() === hash().它只是另一个名称不同的函数,它做同样的事情.它计算输入的加密哈希.

So, first off, let's clear one thing up. openssl_digest() === hash(). It's just another function by a different name that does the exact same thing. It computes a cryptographic hash of the input.

那么,现在我们有一个问题:存储密码时,hash 还是 hash_hmac 哪个更好?

So, now we have the question: When storing passwords, which is better: hash or hash_hmac?

都没有

事实证明,彩虹桌已经死了.仅仅使用 hash($password . $salt) 甚至 hash_hmac($password, $salt) 不足以存储密码.时期.如果您正在这样做,请立即停止.

As it turns out, The Rainbow Table Is Dead. Just using hash($password . $salt) or even hash_hmac($password, $salt) is not good enough for password storage. Period. If you're doing so, stop right now.

原因很简单:计算机(或 GPU)上的计算时间非常便宜.它是如此便宜,以至于暴力破解密码列表足够便宜,您需要担心它.请记住,哈希函数被设计为快速.不贵...

The reason is simple: computation time on a computer (or GPU) is incredibly cheap. It's so cheap, that to brute force a list of passwords is cheap enough that you need to worry about it. Remember, hash functions are designed to be fast. Not expensive...

但是,事实证明,有一种方法可以使这些快速散列函数变得更加昂贵.其实很简单:迭代.

But, as it also turns out, there is a way to make those fast hash functions more expensive. In fact, it's pretty simple: iterate.

现在,我知道你在想什么.您将只循环哈希:

Now, I know what you're thinking. You're going to just loop over the hash:

function hash_password($password, $salt) {
    $hash = hash("sha512", $password . $salt);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash("sha512", $hash);
    }
}

当然,这已经足够了,对吧?不.正如哈希和加密之间的基本区别所述,这不是一个好主意.那么为什么不直接反馈密码和盐呢?

Surely that's good enough, right? Nope. As explained in Fundamental Difference Between Hashing and Encryption, that's not a good idea. So why not just feed back the password and salt in again?

function hash_password($password, $salt) {
    $hash = hash("md5", $salt . $password);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash("md5", $hash . $password);
    }
}

事实上,这正是 PHPASS 使用的(稍作调整,但这是基本算法)...

In fact, this is exactly what PHPASS uses (slightly tweaked, but this is the base algorithm)...

所以现在对 hash_password 的 1 次调用会执行 1000 个哈希周期.

So now 1 call to hash_password executes 1000 hash cycles.

但是我们可以改进吗?

好吧,事实证明,我们可以.下一个合乎逻辑的事情是看看我们是否可以在相同的时间内获得更多的哈希周期.这就是 hash_hmac() 的用武之地.事实证明,HMAC 每次调用时使用 2 个哈希周期.而且因为都是 C,它只需要大约 1.5 倍于 hash() 进行一轮的时间.

Well, as it turns out, we can. The next logical thing to do would be to see if we can get more hash cycles for the same amount of time. And this is where hash_hmac() comes in. As it turns out, HMAC uses 2 hash cycles each time it's called. And because it's all C, it only takes about 1.5 times the amount of time that hash() takes to do a single round.

这意味着如果我们将 hash 替换为 hash_hmac,我们可以立即看到在指定时间内完成的工作量增加了 33%.所以现在我们在这里:

So that means if we replace hash with hash_hmac, we can instantly see a 33% increase in the amount of work being done in a specified time. So now we're here:

function hash_password($password, $salt) {
    $hash = hash_hmac("md5", $salt, $password);
    for ($i = 0; $i < 1000; $i++) {
        $hash = hash_hmac("md5", $hash, $password);
    }
}

这实际上是 PBKDF2 的基本内循环.

And this is actually the basic inner-loop of PBKDF2.

但是我们能变得更好吗?

But can we get better?

是的,再一次,我们可以变得更好.如果我们仔细观察,我们可以看到——除了密码和盐——所有上述算法都使用非常少量的内存.在 sha512 的情况下,他们将使用大约 128 到 256 个字节(缓冲区和状态)来散列密码.由于内存使用量非常小,因此在 GPU 中一次并排运行大量内存是微不足道的.如果我们只能增加内存使用量...

Yes, again, we can get better. If we look closely, we can see that -in addition to password and salt- all of the above algorithms use a very small amount of memory. In the case of sha512, they'll use on the order of 128 to 256 bytes (buffers and state) to hash the password. Since the memory use is so small, it's trivial to run a lot of them at once side-by-side in a GPU. If we could only increase the memory usage...

好吧,事实证明,我们可以简单地使用 bcrypt,这是一种自适应散列算法.它的一个优点是它比上述算法使用更多内存(大约 4 到 5kb).所以它更抵制并行化.并且由于计算成本很高,因此可以抵抗暴力破解.

Well, as it turns out, we can simply use bcrypt, which is an adaptive hashing algorithm. It has an advantage that it uses more memory than the above algorithms (on the order of 4 to 5kb). So it's more resistent to parallelizing. And it's resistent to brute forcing since it's computationally expensive.

幸运的是,它适用于 PHP:

Luckily, it's available for PHP:

crypt($password, '$2y$07$usesomesillystringforsalt$')

注意 crypt() 使用了很多算法,但是 $2y$$2a$ 算法是 bcrypt.

Note that crypt() uses many algorithms, but the $2y$ and $2a$ algorithms are bcrypt.

但是我们可以改进一下吗?

But can we improve on this?

一种.有一种相对较新的算法称为 scrypt.它比 bcrypt 更好,因为它在计算上同样昂贵,但使用更多的内存(大约 20mb 到 40mb 来散列单个密码).因此,它对并行化的抵抗力更强......

Kind-of. There is a relatively new algorithm called scrypt. It's better than bcrypt, because it's just as computationally expensive, but uses a LOT more memory (on the order of 20mb to 40mb to hash a single password). Therefore, it's even more resistent to parallelization...

不幸的是,scrypt 在 PHP 还 中不可用(我正在努力改变它).在此之前,请使用 bcrypt...

Unfortunately, scrypt is not available in PHP yet (I'm working on changing that). Until then, use bcrypt...

在LinkedIn 的近期课程之后,LastFM, Hotmail, Gawker 等,证明很多 人做错了.不要做错,使用经过审查的算法库.使用 CRYPT_BLOWFISH (bcrypt),使用 PHPASS,使用 PasswordLib.但是不要仅仅因为你不想拉依赖就发明你自己的......那只是疏忽.

After the recent lessons from LinkedIn, LastFM, Hotmail, Gawker, etc, the proof is apparent that a lot of people are doing it wrong. Don't do it wrong, use a library with a vetted algorithm. Use CRYPT_BLOWFISH (bcrypt), use PHPASS, use PasswordLib. But don't invent your own just because you don't want to pull a dependency... That's just negligence.

更多阅读:

正确加盐密码 - 针对 Pepper 的案例GPU 加速 PBKDF2多次哈希迭代,每次都添加盐?MD5 解码,他们是如何做到的