我应该如何在C#中散列这些数据?

我应该如何在C#中散列这些数据?,c#,security,hash,C#,Security,Hash,我有一个字符串数据字段,是12个字符,字母数字(字母和数字)。出于安全原因,我需要在此字段上执行单向哈希。我应该使用什么算法来避免冲突(将不同的值散列为相同的值)以获得准确的报告?这会是个好办法吗 Edit: Here is the code based on suggestions in comments so far: public static string GetHashedValue(string Input) { byte[] bytes = System.Text.Enc

我有一个字符串数据字段,是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;
}

我建议您应该使用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;
}

编辑:散列是一种方式,是存储密码的理想方式。如果您想用密钥返回原始值,请使用对称算法。

避免冲突是本世纪的问题。但解决方案只取决于什么对你足够好。
如果您的输入字符串是todo list应用程序的密码,那么Sha256就足够了,但是如果您需要真正强大的安全性,您应该研究您的问题并告诉我们更多信息。

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

加密散列有几个属性,包括(1)预映像阻力,即无法有效地从散列中找到原始值和(2)冲突阻力,即无法有效地找到具有相同散列的一对输入,并且如果给定一个具有散列的输入,则无法有效地找到具有相同散列的另一个输入(抗碰撞能力弱且强)

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

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

因此,您的问题的答案是,在sha256甚至sha512的情况下,只要没有已知的针对这些算法的攻击,您就不太可能发现冲突

现在有针对sha2的攻击,但实际上,仍然不太可能找到碰撞。有关详细信息,请参阅

从很多方面来说,sha2仍然是好的,对于其他人来说,也许不是


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

是的,
SHA256Managed
就足够了,你也可以使用
SHA512Managed
。足够做什么?只有你能告诉我们,这让这个问题在这里偏离主题。足够避免冲突,正如我所说的@DavidG可能您应该将这些字节转换为base64字符串,而不是简单的ASCII。编码会导致数据丢失,因此可能发生冲突的可能性很高。如果不是ASCII@CetinBasoz,什么System.Text.Encoding值可以避免这种情况?还有其他类似UTF8、UTF16等的值。不过,我的源数据都是字母数字。下面是可能的编码:ASCII UTF-16 UTF-32 UTF-7 UTF-8除此之外,
字节
值很可能包含一堆无法打印的ASCII字符。Base64绝对是正确的选择。@JoelCoehoorn,是的,我说“丢失”就是这个意思。@Infin8Loop,绝对是的。每当需要将一些二进制数据存储为“字符串”时(然后再转换回字节)使用base64。所有这些ASCII、UTF8等编码都会导致数据丢失(例如,开始部分的一个字节可能是十六进制0x0,除非使用base64,否则会丢失其余字节).UTF8应该是高度可靠的。如果您确实需要跨平台的语言不可知编码和系统不可知编码,您应该使用UTF16。每个人都喜欢UTF8,因为它向后兼容ascii,并且可能更小(在非亚洲语言中可能更经常)。老实说,这对你来说应该没问题。如果你好奇,我建议你读一读。你能解释一下为什么散列不适合密码散列吗?有趣的是,因为它太快了。预计算和构建彩虹表太容易了。事实上,已经有彩虹表可用,所以你可以尝试打破前映像阻力f或者许多不同类型的输入。例如,您只需下载一个包含字母数字字符的最大长度为9个字符的所有字符串的哈希数据库。现在这非常适合破解密码。:)哦,不,这是关于密码的强大。增加你的字符数,使用任何可以打印的东西,还可以添加一个盐。对我来说看起来很安全。不仅是受攻击的地方可能会限制试用。否则,你对密码有什么建议?对称算法?当然不是。最佳做法是密钥派生有很多轮的函数,例如bcrypt或pbkdf2,有很多轮,一次散列计算大约需要0.2-0.3秒。这样,它就不会被破解。使用普通散列的盐不会有多大帮助,因为计算仍然是快速和可并行计算的。另外,你也不能指望你的用户记住14个以上字符的密码。哦,我明白了现在的困惑。你不是说“散列”对密码不好,而是说专门针对“SHA-2”。哪个相反的答案说SHA-2是好的?我以为你提到了我的答案,我没有说任何关于所选算法的内容。