我已经读过,在对密码进行散列时,许多程序员建议使用BCrypt算法。
我正在使用C#进行编程,并且想知道是否有人知道BCrypt的良好实现?我找到了this page,但我真的不知道它是否是伪造的。
选择密码哈希方案时应该注意什么? BCrypt是一个“好”的实现吗?
首先,一些重要的术语:
Hashing - 获取字符串并生成无法恢复为原始字符串的字符序列的行为。
Symmetric Encryption - (通常简称为“加密”) - 获取字符串并生成一系列字符的行为,这些字符可以通过使用加密它的相同加密密钥解密为原始字符串。
Rainbow Table - 一个查找表,包含特定散列算法中散列的所有字符变体。
Salt - 在散列之前附加到原始字符串的已知随机字符串。
对于.NET Framework,Bcrypt还没有经过验证的参考实现。这很重要,因为无法知道现有实施中是否存在严重缺陷。你可以得到BCrypt for .NET here的实现。我对密码学知之甚少,不知道它是一个好的还是坏的实现。密码学是一个非常深刻的领域。不要尝试构建自己的加密算法。认真。
如果您要实现自己的密码安全性(叹气),那么您需要做几件事:
不幸的是,即使你做了这一切,一个坚定的黑客仍然可能找出密码,它只需要他很长一段时间。那是你的主要敌人:时间。
bcrypt algorithm works because it takes five orders of magnitude longer to hash a password than MD5; (并且仍然比AES或SHA-512长得多)。它迫使黑客花费更多的时间来创建一个彩虹表来查找你的密码,使你的密码不太可能被黑客攻击。
如果你正在腌制和散列你的密码,并且每种盐都不同,then a potential hacker would have to create a rainbow table for each variation of salt,只需要一个彩虹表,一个盐渍+哈希密码。这意味着如果你有100万用户,黑客必须生成100万个彩虹表。如果你为每个用户使用相同的盐,那么黑客只需要生成1个彩虹表来成功破解你的系统。
如果你没有使用密码,那么攻击者所要做的就是为每个实现提供一个现有的Rainbow表(AES,SHA-512,MD5),看看是否匹配哈希值。这个has already been done,攻击者不需要自己计算这些彩虹表。
即使有这一切,you've got to be using good security practices。如果他们可以在您的站点上成功使用其他攻击媒介(XSS,SQL注入,CSRF,et. al.),那么良好的密码安全性无关紧要。这听起来像是一个有争议的声明,但请想一想:如果我可以通过SQL注入攻击获取所有用户信息,或者我可以让您的用户通过XSS,then it doesn't matter how good your password security is向我提供他们的cookie。
其他资源:
注意:请推荐其他好资源。我必须读过几十位作者的十几篇文章,但很少有人像Jeff那样明确地写这个主题。请在您找到它们时在文章中进行编辑。
您不能在.NET中使用BCrypt。您必须使用内置的.NET框架实现中的PBKDF2。它是.NET中唯一可用的加密验证实现,同时也是algorithm recommended by NIST。
由于这个原因,StackId以前使用BCrypt并转移到PBKDF2:
对于那些好奇的人,我们用PBKDF2散列密码。相关代码在这里(http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135),通过几层间接。在之前的迭代中,我们使用BCrypt;但由于它内置于.NET框架中,因此转移到PBKDF2,而BCrypt则要求我们验证实现(不小的任务)。
编辑:在加密术语中验证的含义似乎不容易理解,经过验证的实现意味着它已被加密证明可以无误地实现。这样的成本很容易达到20,000美元或更高。我记得当我正在研究OpenSSL并阅读他们说他们没有完成整个验证过程的地方但是如果你需要完全验证他们可以指出你正确的路径并提到相关的成本。某些政府要求包括验证加密算法的要求。
.NET中的bcrypt实现尚未得到验证。使用未经验证的加密实现,您不能完全确定其中没有故意的恶意错误,例如允许后门进入加密或无意的实现错误导致加密不安全的数据。
2014编辑:对于任何质疑使用经过验证的密码算法算法的必要性的人,请看看在OpenSSL中利用的heartbleed hack造成的破坏。这是使用未经验证的实现的成本。它是安全的......直到你发现任何人都可以读取服务器的整个内存内容。
介绍Heartbleed的变更的作者Robin Seggelmann表示,他“错过了验证包含长度的变量”,并且拒绝提交任何有缺陷的实施意图。在Heartbleed的披露之后,Seggelmann建议关注第二个方面,并指出OpenSSL没有得到足够多的人的评论。
这是未经验证的实现的定义。即使是最小的缺陷也可能导致整个安全性受损。
2015编辑:删除基于推荐的语言并替换为绝对值。嵌入式原创Kevin Montrose对后人的评论。