当前位置:  开发笔记 > 编程语言 > 正文

BCrypt是一个在C#中使用的好散列算法吗?我在哪里可以找到它?

如何解决《BCrypt是一个在C#中使用的好散列算法吗?我在哪里可以找到它?》经验,为你挑选了2个好方法。

我已经读过,在对密码进行散列时,许多程序员建议使用BCrypt算法.

我正在使用C#进行编程,并且想知道是否有人知道BCrypt的良好实现?我找到了这个页面,但我真的不知道它是不是假的.

选择密码哈希方案时应该注意什么?BCrypt是一个"好"的实现吗?



1> George Stock..:

首先,一些重要的术语:

散列(Hashing) - 获取字符串并生成无法恢复为原始字符串的字符序列的行为.

对称加密 - (通常也称为"加密") - 获取字符串并生成一系列字符的行为,这些字符可以 通过使用加密它的相同加密密钥解密为原始字符串.

彩虹表 - 一个查找表,其中包含特定散列算法中散列的所有字符变体.

Salt - 在散列之前附加到原始字符串的已知随机字符串.

对于.NET Framework,Bcrypt还没有经过验证的参考实现.这很重要,因为无法知道现有实施中是否存在严重缺陷.您可以在此处获得BCrypt for .NET的实现.我对密码学知之甚少,不知道它是一个好的还是坏的实现.密码学是一个非常深刻的领域. 不要尝试构建自己的加密算法.认真.

如果您要实现自己的密码安全性(叹气),那么您需要做几件事:

    使用相对安全的哈希算法.

    在每个密码进行哈希处理之前对其进行盐化.

    为每个密码使用唯一的长盐,并使用密码存储盐.

    需要强密码.

不幸的是,即使你做了这一切,一个坚定的黑客仍然可能找出密码,它只需要他很长一段时间.那是你的主要敌人:时间.

该bcrypt算法的工作,因为它需要5个较长的订单哈希比MD5密码 ; (并且仍然比AES或SHA-512长得多).它迫使黑客花费更多的时间来创建一个彩虹表来查找你的密码,使你的密码不太可能被黑客攻击.

如果你正在腌制和散列你的密码,并且每种盐都不同,那么潜在的黑客就必须为每种盐的变化创建一个彩虹表,只需要有一个彩虹表来获取一个盐渍+哈希密码.这意味着如果你有100万用户,黑客必须生成100万个彩虹表.如果你为每个用户使用相同的盐,那么黑客只需要生成1个彩虹表来成功破解你的系统.

如果你没有使用密码,那么攻击者所要做的就是为每个实现提供一个现有的Rainbow表(AES,SHA-512,MD5),看看是否匹配哈希值.这已经完成,攻击者不需要自己计算这些彩虹表.

即便如此,您必须使用良好的安全措施.如果他们可以在您的站点上成功使用其他攻击媒介(XSS,SQL注入,CSRF 等),那么良好的密码安全性无关紧要.这听起来像一个有争议的声明,但想一想:如果我可以通过SQL注入攻击获取所有用户信息,或者我可以让您的用户通过XSS向我提供他们的cookie,那么密码有多好并不重要安全是.

其他资源:

    Jeff Atwood:简化的.NET加密(非常适合散列概述)

    杰夫阿特伍德:我刚刚和你一起登录

    杰夫阿特伍德:你可能错误地存储了密码

    杰夫阿特伍德:速度哈希

注意:请推荐其他好资源.我必须读过几十位作者的十几篇文章,但很少有人像Jeff那样明确地写这个主题.请在您找到它们时在文章中进行编辑.


我对你的陈述有疑问"如果他们能成功使用XSS或SQL注入,那么良好的密码安全性并不重要." 相反,如果他们能够成功地通过XSS或SQL注入您的网站,那么良好的密码安全性就更为重要.这里的关键是"纵深防御" - 你应该在应用程序的每一层都尽可能地加强安全性.
不是真的,盐不必是秘密,每个实例都是唯一的.由于不可能是唯一的(如在世界范围内),随机是下一个最好的事情.此外,[时间戳不是一个好的盐](http://stackoverflow.com/questions/4983915/is-time-a-good-salt/4984044#4984044)因为没有足够的熵.
@Jacco好电话,补充道.虽然那并不重要.您可以简单地使用盐的登录时间戳.它的不同之处在于攻击者需要为每个盐重新计算彩虹表.这就是让它变得困难的原因,而不是它是随机选择的.随机添加会增加另一层障碍,但是一旦攻击者能够看到你的数据库(这是导致我们所有心痛的问题),那就没用了.
@jammycakes绝对; 我的观点丢失了:你不能只说,'嘿,我们哈希并加密我们的密码,"我们没问题!"

2> Chris Marisi..:

不能在.NET中使用 BCrypt.您必须使用内置的.NET框架实现中的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日

(GitHub上的更新链接)

编辑:在加密术语中验证的含义似乎不容易理解,经过验证的实现意味着它已被加密证明可以无误地实现.这样的成本很容易达到20,000美元或更高.我记得当我正在研究OpenSSL并阅读他们说他们没有完成整个验证过程的地方但是如果你需要完全验证他们可以指出你正确的路径并提到相关的成本.某些政府要求包括验证加密算法的要求.

.NET中的bcrypt实现尚未得到验证.使用未经验证的加密实现,您不能完全确定其中没有故意的恶意错误,例如允许后门进入加密或无意的实现故障,导致加密不安全的数据.

2014年编辑:对于质疑使用经过验证的密码算法算法的必要性的任何人,请看看OpenSSL中利用的心脏黑客造成的破坏.这是使用未经验证的实现的成本.它是安全的....直到你发现任何人都可以读取服务器的整个内存内容.

介绍Heartbleed的变更的作者Robin Seggelmann表示,他"错过了验证包含长度的变量"并且拒绝提交任何有缺陷的实施意图.在Heartbleed的披露之后,Seggelmann建议关注第二个方面,并指出OpenSSL没有得到足够多的人的评论.

这是未经验证的实现的定义.即使是最小的缺陷也可能导致整个安全性受损.

2015编辑:删除基于推荐的语言并替换为绝对值.嵌入式原创Kevin Montrose对后人的评论.


引用链接的注释:"[我们]移植到PBKDF2,因为它内置在.NET框架中,而BCrypt将要求我们验证实现".请注意,注释并未说_algorithm_更好,只是SE Dev Team认为内置PBKDF2 _implementation_比外部库(最终是判断调用)更可靠.
这是一个糟糕的建议,我很惊讶它有这么多的赞成.在托管语言中验证BCrypt实现比在C中验证类似于整个SSL实现的内容要轻松得多,Heartbleed完全无关紧要; 你最好提一下类似PHP类型的哈希等式检查问题.另外,虽然在实际意义上很适合,但PBKDF2是KDF,而不是密码散列算法,而BCrypt更适合.无论如何,最近使用Argon2会更有意义,因为有一个经过充分测试的C#库
@DK我甚至认为你不得不要求他们重置密码.在下次登录时(他们提供明文密码),我相信你可以做到.
我想知道SO是如何将所有bcrypt哈希密码迁移到新哈希的?他们不需要使用原始密码来使用新算法对其进行哈希处理吗?
@Piskvor我更新了我的答案.这不是SO团队认为安全的内容,而是内在证明安全或希望安全之间的判断调用.后者在加密方面是不可接受的.
推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有