【问题标题】:How should I hash this data in C#?我应该如何在 C# 中散列这些数据?
【发布时间】:2018-10-26 19:25:42
【问题描述】:

我有一个字符串数据字段,它是 12 个字符,字母数字(字母和数字)。出于安全原因,我需要在此字段上执行单向哈希。我应该使用什么算法来避免冲突(不同的值散列到相同的值)以获得准确的报告?这样可以吗?

Edit: Here is the code based on suggestions in comments so far:

public static string GetHashedValue(string Input)
{
    byte[] bytes = System.Text.Encoding.Unicode.GetBytes(Input);
    bytes = new System.Security.Cryptography.SHA512Managed().ComputeHash(bytes);
    String output = Convert.ToBase64String(bytes);
    return output;
}

【问题讨论】:

  • 是的,SHA256Managed 就够了,你也可以使用SHA512Managed
  • 满足什么?只有你能告诉我们,这让这个问题在这里我很害怕。
  • 足以避免碰撞,正如我所说的@DavidG
  • 可能你应该将这些字节转换为 base64 字符串,而不仅仅是 ASCII。编码会导致数据丢失,因此可能的冲突机会会很高。
  • 如果不是 ASCII @CetinBasoz,什么 System.Text.Encoding 值适合避免这种情况?还有其他的,比如 UTF8、UTF16 等……不过,我的源数据都是字母数字的。以下是可能的编码: ASCII UTF-16 UTF-32 UTF-7 UTF-8

标签: c# security hash


【解决方案1】:

我建议你应该得到一个base64字符串来防止数据丢失,这样你就可以避免高碰撞机会。即:

public static string GetHashedValue(string Input)
{
    byte[] bytes = System.Text.Encoding.Unicode.GetBytes(Input);
    bytes = new System.Security.Cryptography.SHA512Managed().ComputeHash(bytes);
    string output = Convert.ToBase64String(bytes);
    return output;
}

编辑:哈希是一种方式,非常适合存储密码。如果您希望使用密钥返回原始值,请使用对称算法。

【讨论】:

  • 不仅如此,bytes 值还可能包含一堆不可打印的 ascii 字符。 Base64 绝对是要走的路。
  • @JoelCoehoorn,是的,我说的是“损失”。
  • @Infin8Loop,绝对是的。每当您需要将一些二进制数据存储为“字符串”(然后再转换回字节)时,请使用 base64。所有这些 ASCII、UTF8、... 编码都会导致数据丢失(例如,开头的字节之一可能是十六进制 0x0,除非您使用 base64,否则您会丢失其余字节)。
  • UTF8 应该是高度可靠的。如果您绝对需要跨平台语言不可知和系统不可知编码,您应该使用 UTF16。
  • 每个人喜欢 UTF8,因为它向后兼容 ascii 并且可能更小(在非亚洲语言中可能更常见)。老实说,在你的情况下应该没问题。如果你好奇,我推荐阅读en.wikipedia.org/wiki/Comparison_of_Unicode_encodings
【解决方案2】:

我认为您对加密哈希的概念并不熟悉。

加密哈希具有一些属性,包括 (1) 原像抗性,即。您无法有效地从哈希和(2)抗碰撞性中找到原始值,即。你不能有效地找到一对具有相同哈希的输入,并且给定一个带有哈希的输入,你也不能有效地找到另一个具有相同哈希的输入(弱和强的抗碰撞性)。

但是,这并不意味着完全没有冲突。需要有相同哈希值的输入,因为输出的长度是有限的(sha256 和 512 为 256 或 512 位),但输入是有限的但没有界限,即。任意长。你可以很容易地看到输入比输出多得多,所以肯定有冲突。

只是真的很难找到它们,这意味着理想情况下,在加密哈希的情况下,找到冲突的最佳方法是暴力破解,这对于 256 位输出是不可行的,更不用说 512 了。

所以你的问题的答案是,在 sha256 甚至 sha512 的情况下,真的,真的你不太可能找到碰撞只要没有已知的攻击反对那些算法

现在有针对 sha2 的攻击,但实际上,你仍然不太可能找到碰撞。详情请见here

对于许多目的,sha2 仍然是好的,对于其他人来说,也许不是。

请注意,与另一个答案相反,sha2 不擅长的一件事是密码散列。

【讨论】:

  • 你能解释一下为什么散列不适合密码散列吗?
  • 很有趣,因为它太快了。预先计算和构建彩虹表太容易了 - 实际上,已经有彩虹表可用,因此您可以尝试打破许多不同类型输入的原像阻力。例如,您可以简单地下载所有字符串的哈希数据库,最大长度为 9 个字符,包含字母数字字符。现在这对于破解密码非常有用。 :)
  • 哦,不,这是关于密码强度的问题。增加您的字符数并使用任何可以打印的内容,还可以添加盐。对我来说看起来很安全。不仅是受攻击的地方可能会限制试炼。否则,您对密码有何建议?对称算法?
  • 当然不是。最佳实践是具有多轮的密钥派生函数,例如具有如此多轮的 bcrypt 或 pbkdf2,以至于一次哈希计算大约需要 0.2-0.3 秒。这样,它就不会被破解。具有正常哈希的盐不会有太大帮助,因为计算仍然快速且可并行计算。此外,您不能指望您的用户记住 14 个以上字符的密码。
  • 哦,我现在明白了。您并不是说“散列”对密码不好,而是说专门针对“SHA-2”。哪个相反的答案说sha2很好?我以为你提到了我的答案,我没有说任何关于所选算法的内容。
【解决方案3】:

避免碰撞是世纪难题。但解决方案仅取决于对您来说足够好。 如果您的输入字符串是待办事项列表应用程序的密码,那么 Sha256 就足够了,但如果您需要非常强大的安全性,您应该研究您的问题并告诉我们更多相关信息。

【讨论】:

    猜你喜欢
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    相关资源
    最近更新 更多