如何对密码进行哈希?

7

我的下一个任务是加密密码。我正在数据库访问层工作,我的同事提出了这个要求:在一个空的方法中实现SHA-512哈希。我该如何做到呢?


16
不要尝试对密码进行加密,这应该留给安全专家来处理。如果您自己处理可能会出错,进而危及您的组织。最好雇佣专业人士来处理,这样比在攻击成功后清理由于您未意识到导致安全系统漏洞所产生的问题要便宜得多。 - Eric Lippert
4
雇佣专家取决于您的风险水平。如果您存储了大众的私人信息,并且这个密码是唯一的防线,那么是的,请寻找专家。对于普通非机密信息项目,下面列出的大多数示例都足够使用。 - Larry Hipp
1
@tvanfosson:我建议现在停止整个项目的工作,雇佣一位专家。正确处理密码安全问题远远不止于正确实现SHA512算法。 - Eric Lippert
4
@Eric - 我同意,这对于那些在SO上提出基础问题的人来说可能是很好的建议,但我不确定这能够让我的经理满意。也许更好的问题是,“使用现有工具实施安全解决方案需要多专业?”肯定门槛比“你需要能够设计/分析新的加密算法”要低一些。也许,这是你博客的一个话题?我很想深入了解你的观点。 - tvanfosson
1
@Eric - “雇用专家”这个说法有点轻率,而且在很多情况下可能不切实际。接下来的问题是:你在哪里找到这样的专家,如何确保他具备必要的技能? - Joe
显示剩余4条评论
4个回答

10

其实这是一个非常简单的过程:

byte[] data = Encoding.UTF8.GetBytes(stringPasswordForExample);

using(SHA512 sha512 = new SHA512Managed())
{
    byte[] hash = sha512.ComputeHash(data); // Add Per User Salt as per the Below
}

hash 现在包含您想要散列的初始数据的不可逆散列值。另外,请查看MSDN。一些注意事项:

  • 始终使用(长度越长越好,并且每个用户都是唯一的 - 感谢保罗,提供了很好的建议)
  • SHA2 *生成(以及SHA总体)哈希方法是为了速度而构建的,因此它们并不不安全,但它们也不是最安全的。同时还要看一下bcrypt,以及SLaks已经提到过

2
+1,不过值得一提的是,盐应该对每个密码都是唯一的。也许可以改变你的例子来包含盐。 - PaulG

10

在处理密码时,应该使用bcrypt,它比SHA512更安全。

如果您确实需要使用SHA512,则应使用SHA512Managed,正如其他答案提到的那样。
请确保盐值加入哈希中。


2
有趣的,以前没见过 - Pharabus
你在哈希之前没有给明文加盐吗? - user287466
@uncle brad:那就是我的意思。 - SLaks

7

如何对密码进行哈希处理?

使用盐值。真的。

千万不要做这个:

byte[] data = Encoding.UTF8.GetBytes(stringPasswordForExample);

但是这个:
byte[] data = Encoding.UTF8.GetBytes(stringPasswordForExample + salt);

这是最被误解的“行业诀窍”之一。大多数人不知道什么是“盐”,当你向他们解释时,他们认为它毫无意义。
事实是:SHA-512或MD5或某些非常弱的哈希算法,在预计算彩虹表后,没有任何区别。如果存在SHA-65536(我在这里是在开玩笑),则在预计算彩虹表后,它与任何其他哈希算法一样都不会更好。
足够大的“盐”可以使彩虹表变得不可能:

http://en.wikipedia.org/wiki/Rainbow_table

请注意,即使您完全理解哈希、盐和彩虹表之间的关系(因此理解维基百科文章中所述:“通常使用盐与哈希密码一起使用,以使此攻击更加困难,通常是不可行的。”),但您的同事很有可能不理解。就像在这个主题上投赞成票或反对票的大多数人不理解这个主题一样,这是非常可能的。
我曾经在SO上看到过一个回答,它得到了30个赞,其中一个人无法理解什么是盐,却一直用技术词汇来为自己辩护...然而他却得到了所有这些赞(太懒了找问题,但它是史诗级的)。

1
你应该使用 RNGCryptoServiceProvider 为每个新的哈希创建盐,并存储哈希和盐。 - user1228
单独的盐是不够的。哈希函数也应该要慢一些。使用PBKDF2、bcrypt或scrypt。 - CodesInChaos

1

SHA512类

该页面中的C#示例:

byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA512 shaM = new SHA512Managed();
result = shaM.ComputeHash(data);

不要使用快速的SHA-512,而是使用慢速密钥派生函数,例如PBKDF2、bcrypt或scrypt。 - CodesInChaos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接