从哈希值中获取值?
我想从它的哈希值中取回一个字符串?
string str="Hello";
int hashStr=str.GetHashCode(); // hash value of "Hello" is -694847
我可以从散列值中取回 my_string (即“Hello”)吗?
更新
实际上我正在考虑在散列后将密码保存到我的数据库中以确保其安全......
所以这意味着不同的密码甚至具有相同的值?
I am trying to get back a string from its hash value?
string str="Hello";
int hashStr=str.GetHashCode(); // hash value of "Hello" is -694847
can I get back my_string (i.e "Hello") form the hashed value....?
UPDATED
actually i am thinking to save password into my database after hashing to make it secure...
So it means a different password even have same value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
哈希码正好有 2^32 个,但是
string
的数量要多得多。因此,根据鸽子洞原则,必须有多个字符串
s 映射到相同的哈希码。因此,从哈希码到字符串的逆映射是不可能的编辑:响应您的更新。
是的,两个密码可能具有相同的哈希值。这基本上是对上述内容的重述。但您不应该使用
GetHashCode
对密码进行哈希处理。相反,请使用诸如 SHA-2 之类的安全内容。更进一步,永远不要尝试自己构建加密/安全等。找到一个可以为您完成此操作的库。
There are exactly 2^32 many hash codes but way, way more
string
s. Thus, by the pigeonhole principle, there have to be multiplestring
s mapping to the same hash code. Therefore, an inverse map from hash code tostring
is impossibleEdit: Response to your update.
Yes, it is possible for two passwords to have the same hash. This is basically a restatement of the above. But you shouldn't use
GetHashCode
to hash the password. Instead, use something secure like SHA-2.To go one step further, never try to roll your own your encryption/security etc. Find a library that does it for you.
您没有能力实现此代码。
这没什么好难过的。我也没有能力这样做,而且我研究安全系统很多年了。通过研究安全系统,我了解到安全系统要正确使用极其困难,需要多年的经验和复杂领域的详细专业知识 。这就是我知道我没有能力的原因。您认为哈希值可能是可逆的这一事实表明您不是安全专业人员。
我的建议:聘请安全专家来为您完成这项任务。花大钱去建造一个不能真正保护你的资源的糟糕的安全系统是没有意义的。与其现在推出自己的廉价系统并在以后花费更多的钱来清理灾难,不如现在就多花一点钱并获得专业的实施。
此外,GetHashCode 的文档特别指出,它不适合用于密码哈希,因为算法可能随时更改。事实上,哈希算法在 CLR v1 和 CLR v2 之间确实发生了变化,这让每个依赖 GetHashCode 获取密码哈希并升级系统的供应商都崩溃了。 GetHashCode 不稳定,安全,加密强度不高,并且不基于任何行业标准算法< /em>. 在任何情况下都不要将其用于加密哈希。
You are not competent to implement this code.
That's nothing to feel bad about. I'm not competent to do so either, and I've studied security systems for years. By studying security systems I've learned that security systems are insanely difficult to get right, require years of experience and detailed expertise of a complex domain. That's how I know I'm not competent. The fact that you think that hashes might be reversible indicates to me that you are not a security professional.
My advice: hire a security professional to do this task for you. There is no point in spending good money to make a bad security system that doesn't actually protect your resources. Rather than rolling your own cheap system now and spending a lot more money on cleaning up the disaster later, spend a little more up front now and get a professional implementation.
Furthermore, the documentation for GetHashCode specifically states that it is not suitable to be used for password hashing because the algorithm could be changed at any time. In fact the hash algorithm did change between CLR v1 and CLR v2, and that broke every single vendor who relied upon GetHashCode for a password hash who upgraded their system. GetHashCode is not stable, it is not secure, it is not crypto strength and it is not based on any industry standard algorithm. DO NOT UNDER ANY CIRCUMSTANCES use it for crypto hashing.
这里缺少的一个答案是向OP解释散列不是加密。对于第一次需要处理安全问题的初级程序员(曾经包括我自己)来说,哈希和密码学这两个术语常常令人困惑。
编辑更新:
One answer that is missing here is explaining to the OP that hashing is not encryption. The terms hashing and cryptography are often confusing for junior programmers (myself included at one point) who need to deal with security for the first time.
Edit for Update:
这里没有提到的是你应该给你的哈希加盐.. yum yum。
盐是什么/有什么作用。
假设您掌握了某人的数据库,其中充满了哈希密码。如果他们不加盐进行哈希处理,那么“破解”密码就像下载大量字符串的预哈希数据集一样简单。
如果一个字符串的哈希值匹配,那么您很有可能知道密码。即使它不是正确的密码,您仍然可以使用它登录,因为它提供相同的哈希值。
这就是对哈希值加盐的地方。如果您在对密码进行哈希处理之前向密码添加盐(也称为预先确定的随机字符串),那么您就不能只对大量字符串
示例进行预哈希处理。
无盐:
密码:ABCD 哈希为 1234EFG
大量预哈希字符串的哈希值为 1234EFG,可能是也可能不是 ABCD,但它仍然可以工作。
加盐:
密码:ABCD concat 0315927429 哈希为 43BCF1
每个密码都有不同的盐,因此您不能使用一个预计算机哈希查找表,您必须重新计算每个密码的哈希值。
重新计算会非常耗时。现在,盐不必安全储存即可增加很多这种好处。即使您将盐存储在同一张表中,任何人都很难进行哈希查找来尝试反转任何人的密码。
对其他响应者:“这里缺少的一个答案是向OP解释散列不是加密。”
哈希有时被称为“单向加密”。这是一个糟糕的描述,并且增加了您提到的混乱。
Something not mentioned in here is you should salt your hashes.. yum yum.
What a salt is/does.
Lets say you get a hold of someone's DB full of hashed passwords. If they hashed with no salt, then "breaking" passwords would be as easy as downloading a large pre-hashed dataset of a crap-ton of strings.
If the hash from one string matches, then you have a good chance of knowing the password. Even if it's not the correct password, you can still log in with it since it gives the same hash.
This is where salting your hashes comes in. If you add a salt (aka pre-determined random string) to a password before it is hashed, then you can't just pre-hash a ton of strings
example.
No Salt:
Password: ABCD hashes into 1234EFG
Large list of pre-hashed strings hash a hash of 1234EFG, may or may not be ABCD, but it will still work.
With Salt:
Password: ABCD concat 0315927429 hashes into 43BCF1
Each password has a different salt, so you can't use one pre-computer hash lookup table, you'd have to re-compute the hashes for every password.
Re-computing would incredibly time consuming. Now, the salt doesn't have to be securely stored for it to add lots of this benefit. Even if you store the salt in the same table, it would be incredibly hard for anyone to make a hash lookup to try to reverse any one person's password.
To other responder: "One answer that is missing here is explaining to the OP that hashing is not encryption."
Hashes are sometimes refereed to as "One way encryption". This is a bad description and adds to the confusion you mentioned.
正如其他人所说,一般来说你不能这样做,因为字符串到哈希不是一对一的函数;无限数量的字符串,但只有 2^32 ~ 40 亿个哈希值。也就是说,您可以对未加盐的哈希进行字典攻击。让一组计算机计算各种可能的字符串(例如字典单词)的哈希值并找到匹配的哈希值。
As others said, in general you can't do it as string to hash isn't a one-to-one function; infinite number of strings but only 2^32 ~ 4 billion hashes. That said, you can do a dictionary attack against an unsalted hash. Get a cluster of computers to calculate hashes for a wide variety of likely strings (e.g., dictionary words) and find a hash that matches.
您的问题的简短答案是:否。哈希只是一种方式。
如果您想按照更新中所述保护密码,请使用散列算法(MD5、SHA1...)对其进行散列,然后存储在数据库中。当您想验证用户给出的密码时,只需对其进行散列并与数据库中存储的散列进行比较即可。
The short answer to your question is : No. The hash is just one way.
If you want to secure your password as you said in the update, hash it with a hashing algorithmic (MD5, SHA1, ...) then stored in the database. When you want to verify the password given by the user, just hash it and compared to the hash stored in the database.
GetHashCode
不是加密哈希函数,因此它不是不太适合此目的。是的,不同的密码将具有相同的值。即便如此,这仍然使用户的密码更加安全,尽管这可以安全地在客户端而不是服务器端完成以提高保护。在存储密码之前对密码进行哈希处理的目的是确保您的数据库*不能用于确定用户的密码。用户仍然可以使用数据库中的哈希值来冒充您的用户,但了解用户的实际站点密码更有价值,因为您的大部分用户将在其他地方使用相同的密码。
*还有其他类似的攻击,可以防止中间人攻击,但总的来说,这都是为了确保您不会以纯文本形式将用户密码存储在数据库中。
GetHashCode
is not a Cryptographic hash function, so it isn't really appropriate for this purpose.Yes, different passwords will have the same value. Even so, this still makes the user's passwords more secure, though this can safely be done client-side rather than server-side for improved protection. The purpose of hashing passwords before storing them is to make sure your database* cannot be used to determine a user's passwords. A user could still use the hashes stuck in your database to pose as your users, but knowing a user's actually site password is more valuable, since a good chunk of your users will use the same passwords everywhere else.
*There are other similar attacks this protects against like man-in-the-middle attacks, but in general it's all about ensuring you don't store a user's password in your database in plain text.
您无法从散列值中获取值,但您可以做的(几乎每个保存散列密码的网站都是这样做的)是将刚刚输入的密码的散列与您保存的散列进行比较。
关于你的第二个问题,确实可以有多个文本来匹配一个哈希,但它并不像“你好”的哈希等于“再见”的哈希。它更像是“hello”的哈希等于“sdd89sfu7w84haushf9478hfsklehf84hfwuhf...”的哈希。
You can't get back value from hashed value, but what you can do (and this is what is done in almost every website that saves hashed passwords) is to compare the hash of the just-entered password to the hash you've saved.
And about your second question, it is true that there can be more than one text to match one hash, but it's not like the hash of "hello" is equals to the hash of "goodbye". It's more like the hash of "hello" is equals to the hash of "sdd89sfu7w84haushf9478hfsklehf84hfwuhf...".
不要使用 GetHashCode() 对密码进行哈希处理。它不是加密哈希,并且生成的哈希太短。 GetHashCode 设计用于哈希表和类似结构。返回常量值的 GetHashCode() 是有效的(但会大大减慢哈希表的速度)。
对于密码散列有几个陷阱:
您最好不要自己实现,而是改为使用标准密钥导出函数 (KDF),例如 PBKDF2。
.net 框架包含可以为您执行此操作的类:
要检查输入的密码是否正确,您不会解密保存的密码(这是不可能的),而是使用与原始密码相同的盐对输入的密码进行哈希处理,然后比较哈希值。
Don't use GetHashCode() to hash a password. It isn't a cryptographic hash and it's resulting hash way too short. GetHashCode is designed for use in HashTables and similar structures. A GetHashCode() which returns a constant value is valid(but slows down hashtables a lot).
For password-hashing there are several pitfalls:
You better not implement it yourself, but instead use a standard Key Derivation Function (KDF) such as PBKDF2.
The .net framework contains classes to do this for you:
To check if the entered password is correct, you don't decrypt the saved password(which isn't possible), but you hash the entered password with the same salt as the original password, and then compare the hash.