继我以前关于PHP / MySQL的盐渍密码的问题 ,我有一个关于盐的另一个问题。
当有人说“使用随机盐”到预/追加到一个密码,这意味着什么:
- 创建字符的静态1周时间随机生成的字符串 , 或
- 创建字符的字符串,随机每次创建密码的时间变化 ?
如果盐是随机的为每一位用户和存储与哈希密码一起,怎么会是原来的盐曾经收回到验证?
继我以前关于PHP / MySQL的盐渍密码的问题 ,我有一个关于盐的另一个问题。
当有人说“使用随机盐”到预/追加到一个密码,这意味着什么:
如果盐是随机的为每一位用户和存储与哈希密码一起,怎么会是原来的盐曾经收回到验证?
一个新的盐应为每个用户和每个他们改变密码作为最小时间是随机产生的。 不要只依靠一个网站广泛盐例如,作为击败首先使用盐的地步。
使用每个用户独特的盐是这样,如果两个用户具有相同的密码,他们将不会得到相同的结果哈希。 这也意味着蛮力攻击将需要安装针对每个用户单独而不是能够预先计算的彩虹表的网站。
然后,散列存储在数据库中的盐和密码的结果hash(salt + password)
,与沿salt
为每个用户。 可以在单独的列存储这些,或所有在一列(在散列不使用某些字符分隔,所以;
例如)。 只要你可以同时检索你会没事的。
但是,如果你的数据库被泄露,或者是由于有人获得本地访问,或通过SQL注入攻击,那么无论是盐和最终散列将可用,这意味着对用户的密码蛮力攻击将是微不足道的。 为了解决这个问题,所建议的鲁克你也可以使用存储在本地文件作为您的哈希方法的另一个输入站点范围密钥使攻击者也需要知道这一点发起有效攻击。 这意味着你的数据库将不得不受到影响,攻击者需要访问本地文件。 因此,使用hash(hash(salt + secret) + password)
等。
虽然在大多数算法,你的目标是让事情尽可能快地,密码散列要慢下来,这叫做重点加强 (或有时关键拉伸)。 如果需要0.00001秒为您的哈希函数返回,有人可以尝试暴力破解口令100000第二个,直到他们找到一个匹配。 如果需要对您的哈希函数吐出结果1秒,这不是什么大不了的,只要有人登录到你的应用程序而言,但对破解密码,这是一个更大的问题,因为每一次尝试现在就1秒获得因此,这意味着它会采取100,000次,只要测试每一个野蛮强迫密码较之使用你原来的散列函数。
为了使您的哈希函数慢,你只需要多次运行它。 例如,你可以做new_hash = salt + password + previous_hash
10万次。 您可能需要的迭代次数调整到一个较高的值,如果是太快了。 如果您希望以后能够改变的价值,确保存储的迭代次数与用户记录,这样你就不会影响到之前存储的任何密码。
您的使用者记录现在应该有一个字段的格式是这样的“ $<algorithm>$<iterations>$<salt>$<hash>
”(或者作为单独的领域,如果你想)。
当用户输入自己的密码,您可以从本地文件检索盐和数的迭代从数据库和整个站点的秘密和验证,当您运行相同数量与盐和密码迭代,产生的哈希值匹配什么您存储。
如果用户更改他们的密码,那么你就应该产生一个新的盐。
你用没关系的散列方法(但散列算法不*)。 以上我建议hash(hash(salt + secret) + password)
,但同样也可以是hash(hash(salt) + hash(secret) + hash(password))
您使用不会更改您的密码存储的有效性的方法,一个是不是真的比任何其他更安全。 依托如何散列密码和盐一起提供安全性设计被称为通过隐藏的安全性 ,应予以避免。
*你不应该使用MD5或SHA-1,因为这些被认为是不安全的。 使用SHA-2家族,而不是(SHA256,SHA512等)。 ( 参考文献 )
该盐必须与该散列被存储用于验证成为可能。 最好的做法是在每次创建或更改密码时使用不同的盐。
第二种选择是正确的。
传统上,该盐被存储沿着与哈希密码,但是(通常preappended,非加密的在UNIX密码例如 )
更新:在大多数较新的Unix系统中使用的方法是这一 。
动态改变盐是很多比有过一个静态的盐更安全。
也使每个用户唯一的,而不是一个全局盐盐。 每一个用户,例如登录时间进行更改。
Concatanating的盐与密码散列然后它的末端是OK,但是是一种容易被猜到式。 最好的拿出你自己的一个,即编织的盐和密码,以创建一个新的字符串,则散,如MD5(密码+盐)很容易受到字典攻击仍在。