一些数据库来自90年代,现有的身份验证令牌存储为
MD5(salt + password)
很弱其他数据库使用更好的哈希和盐,但仍不足以抵抗来自当今计算机的攻击。但是,我们不想等到人们登录后才能更新其数据库条目。因此,我的计划是简单地获取密码系统当前使用的任何哈希算法的输出,并将其输入bcrypt并将结果存储为新的身份验证令牌,例如
bcrypt(MD5(salt + password), new_secure_salt)
有人看到此程序有缺点吗?在我看来,这不会比使用
bcrypt(password, new_secure_salt)
更糟,但我知道比仅依靠我自己来评估加密协议要好。 我不建议在新应用程序中使用此过程,但是这种方法是我最好的方法,可以立即以对用户透明的方式保护不安全存储的密码的整个数据库。
#1 楼
总体思路是合理的迁移策略。令人高兴的是,所有用户的安全性通过一次操作即可升级,而不是在每个用户假想的下次登录时进行升级。当然,应该存储原始的salt
和new_secure_salt
,或者可能存储某些部分,这些部分可以准确地从用户键入的材料中导出,例如用户名小写。使用
bcrypt(MD5(salt + password), new_secure_salt)
是对MD5(salt + password)
的巨大改进:给定密码熵的密码破解风险因bcrypt中的多次迭代(以及对内存的某些使用)而大大增加。使用MD5(salt + password)
而不是password
丢弃典型密码时,密码熵几乎可以忽略不计(谁在68个密码中选择20个随机字符作为密码?)但是我还是建议通过bcrypt进行scrypt。 Scrypt使用在合法使用密码期间可用的内存,以进一步提高安全性;请从定义scrypt的论文中查看该表:
我能想到的唯一弱点与
salt
上的MD5冲突有关。如果对手有可能选择salt
并几次使用相同的new_secure_salt
获得认证令牌,则有可能按照GaëtanLeurent的实用密钥恢复中的思路来恢复密码的前几个字符。攻击APOP,一种基于MD5的质询响应身份验证(在IJACT中,2008年)。在上下文中这很可能是理论上的,其中
salt
证明是不可恶意攻击的。要排除这种攻击的可能性,将salt
包含在new_secure_salt
中就足够了。上面的理论攻击利用了可行的方法,即找到两个63字节127字节的
salt0
和salt1
,以使MD5(salt0 + 'e') = MD5(salt1 + 'e')
在前两个64字节MD5块中发生冲突。现在假设我们可以获取这些salt0
和salt1
的身份验证令牌;如果密码以e
开头,则这些令牌匹配!相反,几乎可以肯定地如此。这样就可以构造一个测试密码的第一个字符,并在适当数量的查询中对其进行恢复,然后继续输入第二个(也许是第三个)字符;之后,发现碰撞似乎变得非常困难。评论
$ \ begingroup $
谢谢!我喜欢scrypt,但是对于我来说现在太新了,无法信任,并且通过这种方案,我们可以稍后迁移到scrypt。在我正在查看的所有系统中,对手最多只能预测(但不能选择)旧的salt,并且无法控制新的salt(每个用户都是安全的随机且唯一的),因此这种攻击是不切实际的。
$ \ endgroup $
–主要专业
2012年6月18日22:49
$ \ begingroup $
我相信scrypt算法没有任何缺陷,并且比bcrypt更为安全:安全性参数简单,强大并且经过同行评审。我对w.r.t的scrypt实现没有知情的意见。 bcrypt。我也发现scrypt的定义对我来说有点复杂,而且并非完全没有错字。在我的工作领域(智能卡和HSM)中,bcrypt和scrypt都使用不带硬件支持的奇异原语(Blowfish表示bcrypt,Salsa-20表示),因此速度较慢,因此安全性远低于可实现的水平;以及在要求DPA / DFA抵抗的模式下使用哈希。
$ \ endgroup $
–fgrieu♦
2012年6月19日在12:54
$ \ begingroup $
我对此答案进行了修改,但被拒绝了。如果您要进行更改,我将接受此答案。我要问的是,您对语句重新排序,以便它们从最实用到最不适合。首先,该建议似乎有所改进,然后建议使用scrypt作为更好的解决方案,然后讨论理论上的攻击。另请注意,使用随机更改的new_secure_salt可以防止该攻击,因为这是建议的bcrypt用法。
$ \ endgroup $
–主要专业
2012年6月22日下午6:53
$ \ begingroup $
@fgrieu并不是bcrypt和scrypt的重点吗?
$ \ endgroup $
–ZoFreX
14年7月16日在22:00
$ \ begingroup $
@fgrieu您能为我简单地解释一下表1吗?如果我推导说bcrypt的工作因数在硬件x上花费1000毫秒,而推导另一个对scrypt的工作因数在硬件x上也花费1000ms,那么一个哈希比另一个哈希更昂贵?
$ \ endgroup $
– cottsak
16年4月8日在8:49
#2 楼
此策略的一个潜在问题围绕合规性。您可能要遵守各种禁止不安全哈希函数的法规(例如,政府/国防部法规)。您可能有一个非常不愉快的经历,试图向审核小组说明如何将MD5用作用户身份验证的一部分并不意味着“恐怖分子赢了!” ...在最佳情况下,您将获得一个知识渊博的审核小组,可以将复选框分开安全性来自实际的安全性,但这对您来说压力很大(他们不像假阴性那样真正关心假阳性)。在最坏的情况下,他们会剥夺您的操作授权-当然,“只是为了安全”。#3 楼
一个潜在的考虑因素是安全原则的组合可能具有意想不到的漏洞。这并不是说您不能组合使用这种方法,但是大多数组合已经过深入研究,然后由受信任的第三方(学术机构,政府机构或机构)推荐。功能,中间相遇攻击是组合安全原语时意外后果的一个示例。例如,如果知道任意组合的salt +密码,则哈希函数的弱点是多少?那么该信息怎么办?您需要评估所提议的方法,该方法与您所知道的方法相比具有相对未知的暴露特征,并且您正确地确定了已知问题。您是否愿意将操作简便性换成新方法的不确定性?作为实施者,您将能够评估哪种方法最适合您的情况,或者至少表达出两种方法所带来的折衷。
评论
对我来说看起来很好。你的意思是? original_salt + bcrypt(MD5(原始盐+密码),new_secure_salt)
为了使该方案完全起作用,原始盐必须源自存储的某种东西。最好是将原始盐作为new_secure_salt的子字段:确保不能将MD5冲突转换为盐冲突。但是即使这样,bcrypt(MD5(salt + password),new_secure_salt)似乎在各个方面都有所改进,因为密码中的大多数熵都保留在MD5(salt + password)中。但是我建议使用scrypt而不是bcrypt。尤其参见定义scrypt的论文的表1。
附言有关相关问题,请参阅crypto.stackexchange.com/questions/2840/…和crypto.stackexchange.com/questions/2831/…
@IlmariKaronen:完成。文字大大扩展了:-)