我想从哈希值中找回一个字符串?
string str="Hello";
int hashStr=str.GetHashCode(); // hash value of "Hello" is -694847
我可以从散列值中获取my_string(即“Hello”)....?
已更新
实际上我想在散列后将密码保存到我的数据库中以使其安全......
所以这意味着不同的密码甚至具有相同的值?
答案 0 :(得分:16)
正好有2 ^ 32个哈希码,但方式更多string
s。因此,通过pigeonhole principle,必须有多个string
映射到相同的哈希码。因此,从哈希码到string
的逆映射是不可能的
编辑:对您的更新的回复。
实际上我想在散列后将密码保存到我的数据库中以使其安全......
所以这意味着不同的密码甚至具有相同的值?
是的,两个密码可能具有相同的哈希值。这基本上是对上述内容的重述。但是您不应该使用GetHashCode
来散列密码。相反,使用像SHA-2这样安全的东西。
更进一步,永远不要试图推出自己的加密/安全性等。找一个能为你做这件事的图书馆。
答案 1 :(得分:7)
实际上我想在散列后将密码保存到我的数据库中以使其安全
您无权执行此代码。
没什么可惹的。我也没有能力这样做,而且我已经学习了多年的安全系统。通过研究安全系统,我了解到安全系统非常困难正确,需要多年的经验和复杂领域的详细专业知识 。这就是我知道我不能胜任的方式。您认为哈希可能是可逆的这一事实向我表明您不是安全专家。
我的建议:聘请安全专业人员为您完成此任务。没有必要花很多钱来建立一个实际上并不能保护你资源的糟糕安全系统。而不是现在推出自己的廉价系统,并花费更多的钱来清理灾难,现在花一点时间在前面,并获得专业的实施。
此外, GetHashCode的文档明确指出它不适合用于密码哈希,因为算法可以随时更改。事实上,哈希算法在CLR v1和CLR v2之间进行了更改,这使得依赖GetHashCode的每个供应商都破坏了升级其系统的密码哈希。 GetHashCode不是稳定的,它不是安全,它不是加密强度而且它不是基于任何行业标准算法的 < / em>的。 请勿在任何情况下将其用于加密哈希。
答案 2 :(得分:5)
这里缺少的一个答案是向OP解释散列不是加密的。对于需要首次处理安全问题的初级程序员(我自己也包括在内),术语哈希和加密常常令人困惑。
编辑更新:
答案 3 :(得分:3)
这里没有提到的是你应该为你的哈希加盐... yum yum。
盐是什么/做什么。
让我们说你掌握了一个充满散列密码的人的数据库。如果他们没有盐,那么“打破”密码就像下载大量字符串的大型预先散列数据集一样简单。
如果来自一个字符串的哈希匹配,那么您很有可能知道密码。即使它不是正确的密码,您仍然可以使用它登录,因为它提供相同的哈希值。
这就是你的哈希值腌制的地方。如果你在密码被哈希之前添加一个盐(也就是预先确定的随机字符串),那么你不能只是预先哈希大量的字符串
例子。 无盐: 密码:ABCD哈希进入1234EFG 大量预先散列的字符串散列为1234EFG的散列,可能是也可能不是ABCD,但它仍然有效。
用盐: 密码:ABCD concat 0315927429哈希进入43BCF1 每个密码都有不同的盐,因此您不能使用一个预先计算机哈希查找表,您必须为每个密码重新计算哈希值。
重新计算会耗费大量时间。现在,盐不必安全储存,以增加许多这种好处。即使你将盐存储在同一个表中,任何人都很难进行哈希查找以试图反转任何一个人的密码。
对于其他响应者:“这里缺少的一个答案是向OP解释散列不是加密的。”
哈希有时被称为“单向加密”。这是糟糕描述,并增加了您提到的混乱。
答案 4 :(得分:0)
正如其他人所说,一般情况下你不能这样做,因为字符串到哈希不是一对一的功能;无限数量的字符串但只有2 ^ 32~40亿个哈希值。也就是说,你可以对一个未加盐的哈希进行字典攻击。获取一组计算机来计算各种可能的字符串(例如字典单词)的哈希值,并找到匹配的哈希值。
答案 5 :(得分:0)
您的问题的简短回答是:否。哈希只是一种方式。
如果您想要像更新中所说的那样保护您的密码,请使用哈希算法(MD5,SHA1,...)对其进行哈希处理,然后将其存储在数据库中。如果要验证用户提供的密码,只需将其哈希并与存储在数据库中的哈希进行比较。
答案 6 :(得分:0)
实际上我想要拯救 密码进入我的数据库之后 哈希让它变得安全......所以它甚至意味着不同的密码 有相同的价值?
GetHashCode
不是Cryptographic hash function,因此不适合此目的。
是的,不同的密码将具有相同的值。即便如此,这仍然使用户的密码更安全,尽管这可以安全地在客户端而不是服务器端完成,以提高保护。在存储密码之前散列密码的目的是确保您的数据库*不能用于确定用户的密码。用户仍然可以使用数据库中的哈希值作为您的用户,但知道用户的实际站点密码更有价值,因为大部分用户将在其他地方使用相同的密码。
*还有其他类似的攻击可以防止类似中间人攻击,但一般来说,这都是为了确保您不以纯文本形式在数据库中存储用户密码。
答案 7 :(得分:0)
不要使用GetHashCode()来哈希密码。它不是加密哈希,它产生的哈希方式太短。 GetHashCode设计用于HashTables和类似结构。返回常量值的GetHashCode()是有效的(但会大大减慢哈希表的速度)。
对于密码哈希,有几个缺陷:
最好不要自己实现,而是使用标准的密钥派生函数(KDF),如PBKDF2。
.net框架包含为您执行此操作的类:
要检查输入的密码是否正确,您不会解密保存的密码(这是不可能的),但是您使用与原始密码相同的盐来哈希输入的密码,然后比较哈希值。 / p>
答案 8 :(得分:0)
您无法从散列值中获取值,但您可以执行的操作(这是几乎每个保存散列密码的网站所做的)是将刚刚输入的密码的哈希值与哈希值进行比较已经救了。
关于你的第二个问题,确实可以有多个文本匹配一个哈希值,但它不像“hello”的哈希值等于“goodbye”的哈希值。它更像是“hello”的哈希值等于“sdd89sfu7w84haushf9478hfsklehf84hfwuhf ...”的哈希值。