我读过在散列密码时,许多程序员建议使用 BCrypt 算法。
我正在用 C# 编程,想知道是否有人知道 BCrypt 的良好实现?我找到了这个页面,但我真的不知道它是否是假的。
选择密码哈希方案时应该注意什么?BCrypt 是一个“好的”实现吗?
我读过在散列密码时,许多程序员建议使用 BCrypt 算法。
我正在用 C# 编程,想知道是否有人知道 BCrypt 的良好实现?我找到了这个页面,但我真的不知道它是否是假的。
选择密码哈希方案时应该注意什么?BCrypt 是一个“好的”实现吗?
首先,一些重要的术语:
散列- 获取字符串并生成无法恢复为原始字符串的字符序列的行为。
对称加密- (通常简称为“加密”) - 获取字符串并生成可以 通过使用加密它的相同加密密钥解密为原始字符串的字符序列的行为。
Rainbow Table - 一个查找表,其中包含在特定散列算法中散列的所有字符变体。
Salt - 在散列之前附加到原始字符串的已知随机字符串。
对于 .NET Framework,Bcrypt 还没有经过验证的参考实现。这很重要,因为无法知道现有实现中是否存在严重缺陷。您可以在此处获得 BCrypt for .NET的实现。我对密码学知之甚少,无法说出它是一个好还是坏的实现。密码学是一个非常深奥的领域。 不要试图建立自己的加密算法。严重地。
如果您要实现自己的密码安全性(叹气),那么您需要做几件事:
不幸的是,即使你做了所有这些,一个坚定的黑客仍然有可能找出密码,这只会花费他很长时间。那是你的主要敌人:时间。
bcrypt 算法之所以有效,是因为散列密码比 MD5 长五个数量级;(并且仍然比 AES 或 SHA-512 长得多)。它迫使黑客花费更多时间来创建彩虹表来查找您的密码,从而大大降低您的密码被黑客入侵的可能性。
If you're salting and hashing your passwords, and each salt is different, then a potential hacker would have to create a rainbow table for each variation of salt, just to have a rainbow table for one salted+hashed password. That means if you have 1 million users, a hacker has to generate 1 million rainbow tables. If you're using the same salt for every user, then the hacker only has to generate 1 rainbow table to successfully hack your system.
If you're not salting your passwords, then all an attacker has to do is to pull up an existing Rainbow table for every implementation out there (AES, SHA-512, MD5) and just see if one matches the hash. This has already been done, an attacker does not need to calculate these Rainbow tables themselves.
Even with all this, you've got to be using good security practices. If they can successfully use another attack vector (XSS, SQL Injection, CSRF, et. al.) on your site, good password security doesn't matter. That sounds like a controversial statement, but think about it: If I can get all your user information through a SQL injection attack, or I can get your users to give me their cookies through XSS, then it doesn't matter how good your password security is.
Other resources:
Note: Please recommend other good resources. I've must have read a dozen articles by dozens of authors, but few write as plainly on the subject as Jeff does. Please edit in articles as you find them.
You must not use BCrypt in .NET. You must use PBKDF2 as is with the built in .NET framework implementation. It is the only freely available cryptographically verified implementation in .NET along with being the algorithm recommended by NIST.
StackId previously used BCrypt and moved to PBKDF2 for this very reason:
For those curious, we’re hashing passwords with PBKDF2. Relavent code is here ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ), through a few layers of indirection. In an earlier iteration, we were using BCrypt; but moved to PBKDF2 as it is built into the .NET framework, whereas BCrypt would require us to verify an implementation (no small undertaking).
Edit: The meaning of verified in cryptographic terms seems to not be readily understood, a verified implementation means it's been cryptographically proven to be implemented without error. The cost of this can easily reach $20,000 or higher. I recall this when I was doing research on OpenSSL and read where they stated they haven't completed the entire verification process but if you need fully verified that they can point you down the right path for it and mentioned costs associated. Certain government requirements include mandates for verified encryption algorithms.
The bcrypt implementations in .NET have not been verified. Using an unverified encryption implementation you can't be absolutely certain that there is not either intentional malicious faults in it such as allowing a backdoor into what is encrypted or unintentional implementation faults that result in cryptographically insecure data.
2014 edit: For anyone that questioned the imperativeness of using verified cryptopgraphical algorithims look at the devastation that was wrought by the heartbleed hack exploited in OpenSSL. That is the cost of using an unverified implementation. It's secure.... until you find out that any person can just read the entire memory contents of your server.
The author of the change which introduced Heartbleed, Robin Seggelmann, stated that he "missed validating a variable containing a length" and denied any intention to submit a flawed implementation. Following Heartbleed's disclosure, Seggelmann suggested focusing on the second aspect, stating that OpenSSL is not reviewed by enough people.
This is the definition of an unverified implementation. Even the smallest defect can result in crippling the entire security.
2015 edit: Removed recommendation based language and replaced with absolutes. Embedded original Kevin Montrose comment for posterity.