Web应用密码:bcrypt和SHA256(和scrypt) [英] Web app passwords: bcrypt and SHA256 (and scrypt)

查看:652
本文介绍了Web应用密码:bcrypt和SHA256(和scrypt)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着所有最近(例如LinkedIn)密码的讨论,我在看密码哈希实现。经过两杯咖啡和早晨的阅读,我不再是一个密码学家,而是当我开始的时候。我真的不想假装我是。



具体问题




  1. 使用整数唯一用户ID是否失效作为有效的盐? (crypt()只使用16位?)


  2. 如果我只是一次又一次地运行sha256()第二个用尽了那个击败暴力的攻击?


  3. 如果我不得不问这些问题,我应该使用bcrypt ?




讨论/说明:



目标是简单地说,如果我的用户的散列密码泄露了他们:


  1. 不会容易破解,

  2. 破解一个密码不会暴露使用相同密码的其他用户)。

#1是哈希计算必须是昂贵的 - 取一秒或两秒来计算,也可能需要一点或内存(阻止硬件解密)。



bcrypt内置这个内存,并且如果我理解正确,scrypt是更加面向未来的,并且包含最低内存使用要求。



但是,使用sha256()的结果多次可以使用几秒钟,然后存储,同样有效的方法来吃饭最后的循环计数与哈希以后检查提供的密码?



对于#2,对每个密码使用唯一的盐是很重要的。什么还不清楚盐是如何随机(或大)的。如果目标是避免使用mypassword作为密码的所有人使用相同的哈希值,那么仅仅这样做是不够的:

  hash = sha256_hex(unique_user_id + user_supplied_pa​​ssword); 

甚至这个,虽然我不知道它买了什么:

  hash = sha256_hex(sha256(unique_user_id)+ user_supplied_pa​​ssword); 

使用用户ID可以看到唯一的好处,除了我知道它是唯一的,是避免必须与散列一起保存盐。没有什么优势。使用用户的ID作为盐有真正的问题吗?是否没有完成#2?



我假设有人可以窃取用户的散列密码,那么我必须假设他们可以获得任何他们想要的东西 - 包括生成的源代码哈希。那么,在哈希之前添加一个额外的随机字符串(相同的字符串)到密码有什么好处吗?那就是:

 #app_wide_string =一次性生成,随机64位7位*字符*字符串。 
hash = sha256_hex(unique_user_id + app_wide_string + user_supplied_pa​​ssword);

我已经看到建议,但我不明白,用户盐。如果有人想强制攻击,他们会知道app_wide_string,并在运行字典攻击时使用它,对吧?



有没有理由使用bcrypt如上所述滚过我自己?也许事实上,我提出这些问题是足够的理由?



BTW - 我只是计时一个现有的哈希函数和我的笔记本电脑,我可以生成关于7000散列第二。不太常见的一两秒钟。



一些相关链接:



使用sha256作为使用用户ID的散列和盐化



SHA512与Blowfish和Bcrypt

解决方案

Bcrypt很棒,因为您可以从4到31,每个增量创建一个指数所需的时间,我已经实际绘制了它,在14的工作因子已经占用了一秒钟,所以随着计算机变得越来越快,你只需要更改一个参数,当然更新您的密码哈希...



我的主要公司ncern与bcrypt是,如果工作因素设置为高,那么它可能会超载您的系统,因为多个用户正在尝试登录,所以你调整它,这取决于并发登录的数量和系统的资源...



盐仍然是必需的,其主要目的是防止离线攻击,如果盐分太大,那么对手将无法生成查找表,64位盐似乎有点低,bcrypt有128位盐加上工作因素使它对脱机攻击相当挑战...是的,盐应该是随机的每个密码,bcrypt将为你生成一个如果您为每个密码使用相同的盐,那么您已经使对手更加轻松,以通过在线攻击来限制所有密码。



Bcrypt真正在线上攻击如果你已经正确设置了工作因子,因为即使我得到了哈希,也就是说如果'对手'获得哈希值,那么工作因子使整个字典真的很痛苦,花了好几天,如果密码不在字典中,那么我真的很麻烦,因为暴力攻击将是史诗般的,bcrypt的密码位空间相当大虽然有限:)



Sha256可能要花点时间了,但最终电脑会越来越快,攻击相当容易,以为地狱是如此缓慢,这永远不会成为一个问题,而今天我已经在几秒钟内完成了一次在线攻击,几天内的离线攻击,几周内的暴力攻击(遍历整个密码位空间)...


  1. 您希望盐尽可能大,随机使用数字,使我更容易迭代所有可能的ids。

  2. 多个sha256可能需要一秒钟的时间,但在路上它将不再有效,计算机处理能力呈指数级增长,因此您需要一种算法可以这样配置。

  3. 你正在做正确的事情,提出问题和做功课,如果有更多的人这样做,我们不会有这么多的违规行为


With all the recent (e.g. LinkedIn) discussions of passwords I'm looking at password hashing implementations. After two cups of coffee and a morning reading I'm no more a cryptographer than when I started. And I really don't want to pretend that I am.

Specific Questions

  1. Does using a integer unique user ID fail as an effective salt? (crypt() uses only 16 bits?)

  2. If I simply run sha256() on a hash over and over until a second is used up does that defeat the brute-force attacks?

  3. If I have to ask these questions should I be using bcrypt?

Discussion/Explanation:

The goal is simply if my user's hashed passwords were leaked they:

  1. would not be "easy" to crack,
  2. cracking one password would not expose other users that use the same password).

What I've read for #1 is the the hash computation must be expensive -- taking, say, a second or two to calculate and maybe requiring a bit or memory (to thwart hardware decryption).

bcrypt has this built in, and scrypt, if I understand correctly, is more future-proof and includes a minimum memory usage requirement.

But, is it an equally effective approach to eat time by "rehashing" the result of sha256() as many times as needed to use up a few seconds and then store the final loop count with the hash for later checking a provided password?

For #2, using a unique salt for every password is important. What's not been clear is how random (or large) the salt must be. If the goal is to avoid everyone that uses "mypassword" as their password from having the same hash is it not enough to simply do this?:

hash = sha256_hex( unique_user_id + user_supplied_password );

or even this, although I'm not sure it buys me anything:

hash = sha256_hex( sha256( unique_user_id ) + user_supplied_password );

The only benefit I can see from using the user's ID, besides I know it is unique, is avoiding having to save the salt along with the hash. Not much of an advantage. Is there a real problem with using a user's ID as the salt? Does it not accomplish #2?

I assume if someone can steal my user's hashed passwords then I must assume they can get whatever they want -- including the source code that generates the hash. So, is there any benefit to adding an extra random string (the same string) to the password before hashing? That is:

# app_wide_string = one-time generated, random 64 7-bit *character* string.
hash = sha256_hex( unique_user_id + app_wide_string + user_supplied_password );

I have seen that suggested, but I don't understand what I gain from that over the per-user salt. If someone wanted to brute-force the attack they would know that "app_wide_string" and use that when running their dictionary attack, right?

Is there a good reason to use bcrypt over rolling my own as described above? Maybe the fact that I'm asking these questions is reason enough?

BTW -- I just timed an existing hashing function I have and on my laptop and I can generate about 7000 hashes a second. Not quite the one or two seconds that are often suggested.

Some related links:

using sha256 as hashing and salting with user's ID

SHA512 vs. Blowfish and Bcrypt

What is the optimal length for user password salt?

解决方案

Bcrypt is great because you can tune the work factor from 4 to 31, each increment creates an exponentional required time, I've actually graphed it, at a work factor of 14 it's already taking over a second, so as computers get faster and faster you only need to change one parameter, and of course update your password hashes ...

My main concern with bcrypt is that if the work factor is set to high, then it may overload your system as multiple users are trying to login so you have tune it, depending on the number of of concurrent logins and the resources of your system ...

Salts are still required, their main purpose is to deterred off-line attacks, if the salt space is to large, then the adversary won't be able to generate the look up table, 64 bit salt seems a bit low, bcrypt has 128 bit salts coupled with the work factor makes it quite a challenge for offline attacks ... and yes the salt should be random for each password, bcrypt will generate one for you, if you use the same salt for each password then you have made it eassier for the adversary to comprimised all the passwords using an online attack.

Bcrypt really shines for online attacks, if you have set the work factor properly, because even if I get the hash, meant to say if the 'adversary' gets the hash, the work factor makes it really painful to go through an entire dictionary, taking multiple days and if the password isn't in the dictionary, then I'm really in trouble cause a brute force attack will be epic, the password bit space for bcrypt is quite large though finite :)

Sha256 may be taking a bit of time now, but eventually computers will get faster and faster and it'll be fairly easy for attacks, the unix guys thought crypt was so slow it would have never being an issue, and today I have done an online attack in seconds, offline attack in days, a brute force attack (going through the entire password bit space) in weeks ...

  1. you want the salt to be as large and random as possible using only numbers makes it easier for me to iterate over all the possible ids.
  2. multiple sha256 may take a second now but down the road it won't be effective any more, computers processing power grows exponentially and so you want an algorithm that can be configured as such.
  3. you are doing the right thing by asking questions and doing your homework if more people did this we wouldn't have so many breaches

这篇关于Web应用密码:bcrypt和SHA256(和scrypt)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆