PLS HELP: HUGE problem with Hashcode

M

MuZZy

Hi,

Why for god sake they change implementation of String.GetHashCode() from
..NET 1 to .NET 2?

We were storing some user passwords in hashcode, now we can't upgrade
those clients with .NET 2 vesrion of our app as they will not be able to
log in.

I know, we shouldn't have dealt with hashcode in the first place, but we
did. So now my question is - any way to convert hashcode of .NET 1 to
hashcode of .NET 2 or whatever else? If we ask our clients to redo all
their passwords they are gona bit4 and scream out loud...

Please, any ideas are HIGHLY appreciated!

Thank you,
MuZZy
 
N

Nicholas Paldino [.NET/C# MVP]

MuZZy,

That's an error on your part, actually. There is no guarantee that the
hash code generated by GetHashcode will be the same across different
invocations of the same app at different times (outside of the current
execution). So if you run your program, generate a hash code, save it, shut
the program down, run it again, and then generate the hashcode on an object
that is equal to the first, there is no guarantee that it will be the same.

There is no conversion from one to the other. Rather, you should use
one of the hashcode algorithms in the System.Security.Cryptography namespace
to generate consistent hashes.

Hope this helps.
 
M

MuZZy

Nicholas said:
MuZZy,

That's an error on your part, actually. There is no guarantee that the
hash code generated by GetHashcode will be the same across different
invocations of the same app at different times (outside of the current
execution). So if you run your program, generate a hash code, save it, shut
the program down, run it again, and then generate the hashcode on an object
that is equal to the first, there is no guarantee that it will be the same.

There is no conversion from one to the other. Rather, you should use
one of the hashcode algorithms in the System.Security.Cryptography namespace
to generate consistent hashes.

Hope this helps.

Hi Nicholas,

I didn't mean it's Microsoft's error, and i accepted that it was a
design flaw on our side... i just wanted to know if there was a way
out... apparently there isn't one...

Do you know if any of those hashcode algorythms in Security.Cryptography
is open and can be implemented in T-SQL? We are going to need it to
generate some temp passwords and we should do it on the database directly.

Any ideas?

Thank you,
Andrey
 
J

Jon Skeet [C# MVP]

MuZZy said:
Why for god sake they change implementation of String.GetHashCode() from
.NET 1 to .NET 2?

Because they had a better (faster, better distribution, whatever)
implementation?
We were storing some user passwords in hashcode, now we can't upgrade
those clients with .NET 2 vesrion of our app as they will not be able to
log in.

I know, we shouldn't have dealt with hashcode in the first place, but we
did. So now my question is - any way to convert hashcode of .NET 1 to
hashcode of .NET 2 or whatever else? If we ask our clients to redo all
their passwords they are gona bit4 and scream out loud...

As you say, you shouldn't have been using hashcodes for that - there
was never any guarantee that the implementation would stay the same.
Changing to use the .NET 2.0 String.Hashcode is just going to make
things bad again if they change it again. You should use something like
MD5 instead.

You could ship your customers a temporary patch which converts any
typed in password to MD5 now, using the 1.1 implementation to verify
the password. State that if a user doesn't log in between the time they
get the patch and the time they upgrade to the version using .NET 2.0,
the user will have to reset their password.
 
M

MuZZy

Nicholas said:
MuZZy,

That's an error on your part, actually. There is no guarantee that the
hash code generated by GetHashcode will be the same across different
invocations of the same app at different times (outside of the current
execution). So if you run your program, generate a hash code, save it, shut
the program down, run it again, and then generate the hashcode on an object
that is equal to the first, there is no guarantee that it will be the same.

There is no conversion from one to the other. Rather, you should use
one of the hashcode algorithms in the System.Security.Cryptography namespace
to generate consistent hashes.

Hope this helps.
Hi Nichloas,

I just looked up MSDN and it says this about String.GetHashcode():
A hash function must have the following properties:

--------- quote ------------------------
If two objects of the same type represent the same value, the hash
function must return the same constant value for either object.
For the best performance, a hash function must generate a random
distribution for all input.
The hash function must return exactly the same value regardless of any
changes that are made to the object.
For example, the implementation of GetHashCode provided by the String
class returns unique hash codes for unique string values. Therefore, two
String objects return the same hash code if they represent the same
string value. Also, the method uses all the characters in the string to
generate reasonably randomly distributed output, even when the input is
clustered in certain ranges (for example, many users might have strings
that contain only the lower 128 ASCII characters, even though a string
can contain any of the 65,535 Unicode characters).
--------- quote ------------------------

So it explicitly says that, opposed to what you say, hash code of two
equal strings has to be equal.
I also haven't seen any word about possible incompatibility of generated
hash code between .NET versions - if you know where does it say it,
please point it to me.
In any case, why System.Security.Cryptography.MD5 hash is version-proof
and String.GetHashcode is not?

Any comments are appreciated!

Thank you,
MuZZy
 
W

William Stacey [MVP]

HASHBYTES() is in sql2005 - not sure about 2000, but look for "hash" in the
help.

--
William Stacey [MVP]

| Nicholas Paldino [.NET/C# MVP] wrote:
| > MuZZy,
| >
| > That's an error on your part, actually. There is no guarantee that
the
| > hash code generated by GetHashcode will be the same across different
| > invocations of the same app at different times (outside of the current
| > execution). So if you run your program, generate a hash code, save it,
shut
| > the program down, run it again, and then generate the hashcode on an
object
| > that is equal to the first, there is no guarantee that it will be the
same.
| >
| > There is no conversion from one to the other. Rather, you should
use
| > one of the hashcode algorithms in the System.Security.Cryptography
namespace
| > to generate consistent hashes.
| >
| > Hope this helps.
| >
| >
|
| Hi Nicholas,
|
| I didn't mean it's Microsoft's error, and i accepted that it was a
| design flaw on our side... i just wanted to know if there was a way
| out... apparently there isn't one...
|
| Do you know if any of those hashcode algorythms in Security.Cryptography
| is open and can be implemented in T-SQL? We are going to need it to
| generate some temp passwords and we should do it on the database directly.
|
| Any ideas?
|
| Thank you,
| Andrey
 
G

Guest

MD5 is an Internet standard, published in RFC 1321. This and other hashes,
like the SHA series of hashes, are true cryptographic hashes and when applied
to the same data, must produce the same results over time. For most
implementations of a hash or encryption algorithm, they remain version
independent (except for the new PGP Corporation who think it is ok for
encryption results and reliability to depend upon the data being encrypted).

The only thing that generally changes the results is if the vendor
determines that there was a flaw in their implementation and they correct it.
In that case, you'd be out of luck but that rarely happens (again, except
with PGP).

If you use the Cryptography namespace to do your hash, and I'd suggest using
SHA-512 over MD5, then your passwords should work over multiple versions of
the .Net framework.

As I replied in your later post about this same topic, the documentation for
String.GetHashCode() very specifically states that the GetHashCode
implementation may change from version to version.

You are correct about what Nicholas said (it is not too often you'll catch
him in an error though). The GetHashCode result will be the same every time
you run it against the same string as long as you are still using the same
version of the framework but even a patch to the framework could change the
behavior so the lesson you've learned the hard way is don't persist hashcodes
other than true cryptographic hashes.
 
J

Jon Skeet [C# MVP]

So it explicitly says that, opposed to what you say, hash code of two
equal strings has to be equal.

It has to be equal within the same process, but there's no guarantee
that it will be equal to another run even in the same version of .NET.
I also haven't seen any word about possible incompatibility of generated
hash code between .NET versions - if you know where does it say it,
please point it to me.

From the "Remarks" section of String.GetHashCode:

<quote>
The behavior of GetHashCode is dependent on its implementation, which
might change from one version of the common language runtime to
another.
In any case, why System.Security.Cryptography.MD5 hash is version-proof
and String.GetHashcode is not?

Because MD5 is a hash which is *meant* to be persisted, and which is
explicitly specified.
 
G

Guest

Dale said:
If you use the Cryptography namespace to do your hash, and I'd suggest using
SHA-512 over MD5, then your passwords should work over multiple versions of
the .Net framework.

I agree with using a better hash than MD5. Advances in cryptographic
attacks and processing capabilities are making all the existing 128bit hashes
questionably secure. While at present there's no need to do an emergency
update, if you're starting a new project, or in the OPs case being forced to
change you don't want to use something in danger of being obsoleted in the
relatively near future.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top