Scrypt + Bcrypt =级联散列
一般来说,级联算法很少是一个好主意。级联在使软件更复杂、响应更慢方面效果很好,这几乎是不可取的。级联的通常“理由”是它应该以某种方式(可能神奇地)抵抗一种算法的完全破坏,而不是另一种算法的完全破坏。实际上,情况并非如此,原因如下:
有几种“级联”方法,它们做的事情不同。例如,如果你有散列函数f和g,并且你想防止原像,那么级联f(g(x))可能会起作用;但是如果你想防止碰撞,那就是f(x)||g(x)是有意义的(即连接,而不是组合)。要求级联的人很少在这方面有足够的深度思考他们真正想要的东西。
让我们面对现实吧,这已经不是 1938 年了。算法本身从来都不是弱点;弱点在于它是如何被(误用)的。层叠就像看着木屋上的钢门,并声称它还应该有一个额外的、沉重的挂锁。这是避免处理真正的安全问题的一种伟大且历史悠久的方法。
在密码散列的特定情况下,有一个明显的弱点,那就是密码本身:密码是可猜测的。所以我们想要慢速散列函数,我们通过自己投入更多的 CPU 来打败攻击者(即我们增加迭代次数,使散列尽可能昂贵;攻击者的优势在于他可以在与诚实的服务器相比)。服务器的CPU是他的防线。级联意味着精确地浪费生命力,只是为了让事情更能抵抗传说中的密码分析破解的模糊感觉。
所以不,不要级联。充其量,它只会让你的生活更艰难。更常见的是,它或多或少会直接降低安全性。
看到我写了那篇博文,我想我会插话的。首先,让我解释一下,这是一个 5 分钟的快速文章,所以它不是一些经过充分分析的理论,更像是一个即兴评论。我之所以写它,是因为当时我看到了几次讨论,争论哪种特定算法是最好的。
最初的观点是,与其争论哪个更好,不如同时使用两者并完成它。
自从写了这篇文章以来,我在该领域做了相当多的研究,显然我夸大了这些好处。简单地做类似 sha256(blowfish(data)) 的事情并不像听起来那样抵抗攻击。有办法实现它,但正确地做到这一点需要对密码学有一些扎实的理解,有一些权衡,而且很容易搞砸。您不太可能降低它的安全性,但对于最有可能的攻击而言,收益微乎其微。
我的那篇文章完美地说明了正确进行密码学是多么困难,以及你应该如何非常小心地实施它。组合算法的概念听起来非常合乎逻辑,但是当你坐下来正确分析它时,结果并不像预期的那么好,或者在某些情况下甚至可能更糟。