Answers:
首先,一些重要的术语:
散列 -采取字符串并产生一系列不能还原为原始字符串的字符的行为。
对称加密 -(通常简称为“加密”)-采取一个字符串并产生一系列字符的动作,这些字符序列可以 通过使用对其进行加密的相同加密密钥来解密为原始字符串。
彩虹表 -查找表,其中包含在特定哈希算法中哈希的所有字符变体。
盐 -在散列之前附加到原始字符串的已知随机字符串。
对于.NET Framework,Bcrypt尚没有经过验证的参考实现。这很重要,因为无法知道现有实现中是否存在严重缺陷。您可以在此处获得BCrypt for .NET的实现。我对密码学还不够了解,很难说它是一个好实现。密码学是一个非常深的领域。 不要尝试构建自己的加密算法。说真的
如果要实现自己的密码安全性(叹气),那么您需要做几件事:
不幸的是,即使您做了所有这些事情,一个坚定的黑客仍然可以潜在地找出密码,这只会花很长时间。那是您的主要敌人:时间。
该bcrypt算法的工作,因为它需要5个数量级更长的时间来散比MD5密码 ; (并且仍然比AES或SHA-512长得多)。它迫使黑客花费更多的时间来创建彩虹表来查找您的密码,从而大大减少了密码被黑客入侵的可能性。
如果您正在对密码加盐和散列,并且每种盐都不同,那么潜在的黑客将不得不为salt的每种变体创建一个彩虹表,只为一个盐+哈希密码创建一个彩虹表。这意味着,如果您有100万用户,那么黑客必须生成100万个彩虹表。如果您为每个用户使用相同的盐,那么黑客只需生成1个彩虹表即可成功入侵您的系统。
如果您不给密码加盐,那么攻击者所需要做的就是为其中的每种实现(AES,SHA-512,MD5)提取一个现有的Rainbow表,然后看看是否与哈希匹配。这已经完成,攻击者无需自己计算这些Rainbow表。
即使有所有这些,您也必须使用良好的安全做法。如果他们可以在您的站点上成功使用其他攻击媒介(XSS,SQL Injection,CSRF 等),则良好的密码安全性无关紧要。这听起来像是一个有争议的声明,但请考虑一下:如果我可以通过SQL注入攻击获取所有用户信息,或者可以让您的用户通过XSS给我他们的cookie,那么您的密码有多好都没关系安全是。
其他资源:
注意:请推荐其他好的资源。我一定已经阅读了数十位作者的十几篇文章,但很少有文章像Jeff一样清楚地写过。找到后,请在文章中进行编辑。
您不得在.NET中使用 BCrypt。您必须像使用内置.NET Framework实现一样使用 PBKDF2。它是.NET中唯一免费提供的经过密码验证的实现,并且是NIST推荐的算法。
由于这个原因,StackId以前使用BCrypt并移至PBKDF2:
对于那些好奇的人,我们使用PBKDF2对密码进行哈希处理。 通过几层间接访问,相关代码在这里( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135)。在较早的迭代中,我们使用BCrypt。但由于它已内置到.NET框架中而移至PBKDF2,而BCrypt则要求我们验证实现(不小的工作)。
凯文·蒙特罗斯(Kevin Montrose),2011年5月27日
编辑:用密码术语进行验证的含义似乎不容易理解,经过验证的实现意味着已被加密证明没有错误地实现。这样做的成本很容易达到20,000美元或更高。我在进行OpenSSL研究时回想起了这一点,并读到他们表示尚未完成整个验证过程的地方,但是如果您需要充分验证他们可以为您指出正确的道路,并提到相关的费用。某些政府要求包括对经过验证的加密算法的强制要求。
.NET中的bcrypt实现尚未经过验证。使用未经验证的加密实现,您不能绝对确定其中没有故意的恶意错误,例如允许后门进入加密的内容,或者是由于意外的实现错误而导致的密码不安全的数据。
2014编辑:对于任何质疑使用经过验证的密码算法的必要性的人,请看一下OpenSSL中令人发指的骇客所造成的破坏。那就是使用未经验证的实现的成本。它是安全的...。直到您发现任何人都可以读取服务器的整个内存内容为止。
引入Heartbleed的更改的作者Robin Seggelmann表示,他“错过了验证包含长度的变量”,并否认有意提交有缺陷的实现。在Heartbleed公开之后,Seggelmann建议着重于第二个方面,指出OpenSSL没有得到足够多的人的审查。
这是未经验证的实现的定义。即使是最小的缺陷也可能导致整个安全性受损。
2015编辑:删除了基于推荐的语言,并替换为绝对语言。内嵌原始凯文·蒙特罗斯(Kevin Montrose)的后人评论。