您好我有关于MD5 Hash / Salting的问题。
我最近阅读了很多关于散列和盐析的内容,我明白我应该为每个密码使用不同的盐,并且我不应该使用像用户名这样的东西,因为理想情况下盐应该是完全独特的。但我不明白为什么建议将这个盐与密码一起存储在数据库中?
如果攻击者获得哈希和盐,这不是很糟糕吗?我理解攻击者更难,因为独特的盐确保他无法检查所有密码的单个计算哈希值。但是,保持盐的一部分隐藏不是更好吗?
我想的是将盐分成两部分。第一部分像往常一样存储在数据库中,第二部分(较小)部分在我的应用程序中硬编码。攻击者几乎不可能获得完整的盐,因为他必须渗透应用程序服务器和数据库。
这是一个很好的解决方案吗?盐仍然是独特的,但是所有的盐都会以相同的顺序结束。
答案 0 :(得分:10)
攻击者“允许”知道盐 - 您的安全性必须设计为即使知道盐仍然是安全的。
盐有什么作用?
Salt使用预先计算的“彩虹表”帮助抵御暴力攻击
对于攻击者来说,盐使蛮力更加昂贵(在时间/记忆方面)
计算这样一个表是很昂贵的,通常只有当它可以用于多个攻击/密码时才会这样做
如果您对所有密码使用相同的盐,则攻击者可以预先计算此类表格,然后将您的密码暴力强制为明文...
只要你为每个密码生成一个新的(最好的cryptogrpahically强)随机盐你想存储哈希就没有问题。
根据您使用MD5的方式,这是一个弱点,因为MD5不再被视为“加密安全”
如果您想进一步加强安全性
你可以多次计算哈希值(散列哈希等) - 这不会花费你太多但是它会使暴力攻击/计算“彩虹表”更加昂贵......请不要发明自己 - 已经过验证的标准方法,例如参见http://en.wikipedia.org/wiki/PBKDF2和http://www.itnewb.com/tutorial/Encrypting-Passwords-with-PHP-for-Storage-Using-the-RSA-PBKDF2-Standard以及http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx
现在使用这种机制强制,因为“CPU / GPU时间”(可用于彩虹表/蛮力等攻击)越来越广泛可用(参见例如事实上,亚马逊的云服务是世界上最快的超级计算机之一,并且任何人都可以使用相对较少的数量)!
不建议将盐分成2块,一块硬编码/常量和一个独特的部分!
根据所使用的算法,这可能是帮助攻击者破坏安全性的弱点。我强烈建议不要这样做,除非你能用数学证明它不会削弱你的安全性(这很难做到恕我直言)。
如果您正确实施安全性,攻击者根本不会有任何问题知道您的完整盐...
更新(根据评论):
RFC 2898 is an important reference on PBKDF2。在4.1节中,它讨论了向盐添加一部分
salt应该包含明确区分的数据 不同的操作和不同的密钥长度
这让恕我直言与OP的要求无关。 RFC讨论了密钥长度等信息,并与随机盐一起作为附加部分加入。这与包含描述其包含的数据的特定方面的标题部分的文件格式非常相似。这不会削弱安全性,并且在需要不同系统之间的互操作性的情况下可能非常有用。
相反,OP要求的基本上只是在DB中存储一部分盐,同时保持应用程序中其他(较小)部分硬编码,这意味着DB中的盐不完整......这样做意味着失去盐的熵(即具有8位恒定的64位盐实际上仅与56位盐一样安全),这反过来导致盐提供的安全性削弱(至少对于我能想到的任何算法)现在关闭)......这与OP意图(提高安全性)相矛盾。
更新2(根据与owlstead的讨论):
您可以使用一个完全存储在数据库中的唯一且随机的盐,使用PBKDF2在明文之前添加一些“秘密”(可以在您的应用程序中进行硬编码)BEFORE哈希...虽然它可以帮助我通过默默无闻安全 IMO。