use*_*085 70 security encryption open-source salt rainbowtable
据我了解,生成盐的最佳做法是使用源代码中存储的一些神秘公式(甚至魔术常量).
我正在研究一个我们打算作为开源发布的项目,但问题是源代码是生成盐的秘密公式,因此能够在我们的网站上运行彩虹表攻击.
我认为很多人在我面前都考虑过这个问题,我想知道最佳做法是什么.在我看来,如果代码是开源的话,根本就没有盐,因为盐可以很容易地进行逆向工程.
思考?
Jac*_*cco 227
由于关于盐渍哈希的问题经常出现,并且似乎对这个问题存在一些混淆,我扩展了这个答案.
salt是固定长度的随机字节集,添加到散列算法的输入中.
向散列添加随机盐可确保相同的密码将产生许多不同的散列.salt通常与散列函数的结果一起存储在数据库中.由于以下几个原因,对哈希进行盐析是很好的:
salt不是一个秘密密钥,而是通过使哈希函数特定于每个实例来使"盐"起作用.使用salted哈希,没有一个哈希函数,但每个可能的盐值都有一个哈希函数.这可以防止攻击者攻击N个散列密码的次数少于攻击一个密码的N倍.这是盐的重点.
"秘密盐"不是盐,它被称为"密钥",它意味着您不再计算哈希值,而是计算消息验证码(MAC).计算MAC是一项棘手的业务(比简单地将一个键和一个值拼接到一个哈希函数中要复杂得多)并且它完全是一个非常不同的主题.
对于使用它的每个实例,盐必须是随机的.这可确保攻击者必须分别攻击每个salted哈希.
如果你依赖你的盐(或盐算算法)是秘密的,你进入安全通过晦涩的领域(将无法工作).最有可能的是,你没有从盐保密中获得额外的安全性; 你只是得到了温暖的模糊安全感.因此,它不会让您的系统更安全,而只会让您远离现实.
从技术上讲,盐应该是独一无二的.对于每个散列密码,salt的要点是不同的.这意味着全世界.由于没有按需分配独特盐的中央组织,我们必须依靠下一个最好的东西,即使用不可预测的随机发生器进行随机选择,最好是在足够大的盐空间内使碰撞不可能(使用相同的两个实例)盐值).
尝试从一些"大概是唯一的"数据中获取盐是很诱人的,例如用户ID,但是由于一些令人讨厌的细节,这些方案经常会失败:
如果您使用例如用户ID,则攻击不同系统的一些坏人可能只汇集其资源并为用户ID 1到50创建预先计算的表.用户ID在系统范围内是唯一的,但不是全球性的.
这同样适用于用户名:每个Unix系统都有一个"root",但世界上有很多根."root"的彩虹表值得付出努力,因为它可以应用于数百万个系统.更糟糕的是,那里还有很多"bob",很多人没有系统管理员培训:他们的密码可能很弱.
唯一性也是暂时的.有时,用户会更改密码.对于每个新密码,必须选择新的盐.否则,攻击者获得旧密码的哈希值,并且新的哈希值可能会同时攻击两者.
使用从加密安全,不可预测的PRNG获得的随机盐可能是某种矫枉过正,但至少它可以证明可以保护您免受所有这些危害.这不是为了防止攻击者知道单个盐是什么,而是为了不给他们提供大量,可用于大量潜在目标的大目标.随机选择使目标尽可能薄.
使用随机,均匀分布的高熵盐.无论何时创建新密码或更改密码,都要使用新的盐.将盐与散列密码一起存储.喜欢大盐(至少10个字节,最好是16个或更多).
盐不会将错误的密码变成好的密码.它只是确保攻击者至少为他打破的每个错误密码支付字典攻击价格.
有用的资料来源:
stackoverflow.com:用于密码哈希的非随机盐
Bruce Schneier:实用密码学(书籍)
Matasano安全性:足够使用Rainbow Tables
usenix.org:自1976年以来Unix crypt使用盐
owasp.org:为什么要加盐
openwall.com:盐
免责声明:
我不是安全专家.(虽然这个答案由Thomas Pornin审查)
如果有任何安全专业人员发现错误,请评论或编辑此维基答案.
kem*_*002 18
真正的盐只需要每个条目都是唯一的.即使攻击者可以计算盐的含量,也会使彩虹表极难创建.这是因为salt在被散列之前被添加到密码中,因此它有效地增加了彩虹表必须包含的条目总数,以获得密码字段的所有可能值的列表.
由于Unix变得流行,存储密码的正确方法是附加一个随机值(盐)并散列它.将盐分保存在以后可以到达的地方,但是你希望那些坏人不会得到它.
这有一些很好的效果.首先,坏人不能只列出预期的密码,如"Password1",将它们哈希到彩虹表中,然后通过密码文件查找匹配项.如果你有一个很好的双字节盐,他们必须为每个预期的密码生成65,536个值,这使得彩虹表不那么实用.其次,如果你能从查看密码文件的坏人那里得到盐,你就会更难以计算出可能的值.第三,你已经让坏人无法确定某个人是否在不同的网站上使用相同的密码.
为此,您将生成随机盐.这应该以均匀的概率生成所需范围内的每个数字.这并不困难; 一个简单的线性同余随机数发生器可以很好地完成.
如果你有复杂的计算来制盐,那你做错了.如果你根据密码计算它,那你就错了.在这种情况下,你所做的只是使散列复杂化,而不是在功能上添加任何盐.
没有人擅长安全性会依赖于隐藏算法.现代密码学基于已经过广泛测试的算法,并且为了进行广泛测试,它们必须是众所周知的.一般来说,人们发现使用标准算法比使用标准算法更安全,并希望它是好的.如果代码是开源的并不重要,那么坏人通常仍然可以分析程序的功能.
归档时间: |
|
查看次数: |
22858 次 |
最近记录: |