123
-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|398|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
Socoder -> Off Topic -> Are salt hashes secure?

Sun, 09 Oct 2011, 06:09
Afr0
I'm trying to implement a working authentication system using C#.
Now we all know that the username isn't an issue. It can be sent as plaintext.
I've been using an SRP (Secure Remote Password) implementation . Problem is, I don't like the license (GPL).
Therefore I tried another implementation, Bouncy Castle.
Problem is, it doesn't seem to work! Whatever I do, I cannot seem to make the client and server generate the same secrets!

Therefore I was wondering... is it *really* safe to send a password across the wire as a "one-way" hash (we all know by now there's no such thing as a "one-way" hash), and then use the password, if it matches the hash in the database, as the key for encryption?

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Sun, 09 Oct 2011, 11:15
HoboBen
Are you asking if Secure Remote Password is secure, or if using a simpler hashed password authentication is secure?

If the former, then yes, it's used by large corporations and was written by people who are far better qualified in that area than you or me, and it's likely to be more secure than anything you or me could ever write.

---

But regarding hashes:

Essentially, yes, for a good implementation you can assume hashes are one-way.

The important thing is that any hashing mechanism should be as slow as possible (perhaps by performing several hashes in a loop).

A good user will only need to call this mechanism once, so if it takes ~10 milliseconds, it's negligible compared to the cost of sending data to the server and waiting for a reply (obviously an acceptable time depends on your application).

A bad user trying to brute-force hashes at 10 milliseconds each will be able to do 100 per second, or 360,000 per hour.

A six-letter, lowercase, letters-only password (i.e. a really simple one like 'abcdef') has a potential 26^6 combinations = 308,915,776 combinations. This will take roughly a month to brute force to the original password at 10 milliseconds each.

If you add a unique 12-letter salt for every user, this quickly becomes billions of years. Clearly this hash is practically one way.

---

Saying that there are still issues:

Collisions: a malicious user may not be able to brute force the original password, but they could find a password that has the same hash (and log in). To reduce this, use a hashing algorithm that generates longer hashes (e.g. sha512 instead of sha256, etc).

Interception: a malicious user may not know the original password, but if they can intercept the hash, they can authenticate using that directly. (This also applies to session hashes).

Guessing: a weak password can obviously still be guessed. Consider limiting failed password attempts per IP address.


-=-=-
blog | work | code | more code
Sun, 09 Oct 2011, 13:46
Afr0
I know that SRP is perfectly safe.
I realized that the reason it wasn't working is probably because I was doing something silly with the decryption (Im' using ARC4 to encrypt packets), but nevertheless, I feel like using salty hashes is much easier to implement and maintain.
The implementation I'm using should be fairly secure because it uses native .NET calls only.
The only weakness is that I'm currently required to send the salt across the wire in order to hash the password in the DB and compare it with the client's hash.
In a live, production environment it would probably be safer to just find a way to hash passwords before they're stored in the DB. But then I'd have to use a static salt, which could be lifted from a disassembled client.
The salt I'm using right now is generated once per login, which is why I have to send it to the server.
I'll have to try to figure out what's safer...

Edit: Regardless of whether or not the salt is static, wouldn't a custom rainbow-table have to be generated that adds the salt to each hash?
In that case, that's a heck of a lot of work in order to retrieve a password...

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Sun, 09 Oct 2011, 14:08
HoboBen
The stuff in your DB should be the salted hash. The salt should be secret, nothing the user should know.

(You may have to hash the password twice when you store it in the database, so the user can send you one hash, then you hash+salt that, then compare that to the hash saved in the DB)

You can mix things up a bit by using the username as a salt in the client's hash though -- the objective there is to prevent rainbow-tables from working at all.

--- What are you making, by the way? It sounds exciting!

-=-=-
blog | work | code | more code
Sun, 09 Oct 2011, 15:18
Stealth
HoboBen If you add a unique 12-letter salt for every user, this quickly becomes billions of years.


You should always assume this can and will be compromised.

HoboBen You may have to hash the password twice when you store it in the database, so the user can send you one hash, then you hash+salt that, then compare that to the hash saved in the DB


This is an excellent solution.

-=-=-
Quit posting and try Google.
Sun, 09 Oct 2011, 16:19
JL235
With some hashing functions, hashing the same values multiple times can actually expose information about the original values, making it easier to decrypt.

One small point, there are a number of libraries distributed under GPL which include a 'classpath exception' (also known as GPL Linking Exception). In short, this means you can use the library with non-GPL code, as long as it's just used as a library linked to your application, and was in no way altered.

I don't know about SRP, but you could have a look at it's license, to check if there are any exceptions regarding linking to it. If there are, then it should be safe to use with your non-GPL program, if it's just being linked to as a library.
Sun, 09 Oct 2011, 21:27
Afr0
JL: The license is a standard GPLv2 license, but it states I am free to use other licenses as well.
The implementation of SRP I'm referring to isn't actually a library, it's just a couple of *.cs files.
I'm not well-versed in legalese, but what I'm worried about is that my project (which is generally licensed under Mozilla) will be forced to relicense all its files under the GPL if I utilize the implementation.
If anyone's wondering, the implementation is located here and consists of "SecureRemotePassword.cs" and "BigInteger.cs".

Hobo: Adding a salt to a hash sent by the client is an excellent idea!

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Sun, 09 Oct 2011, 21:52
Afr0
Sending an unsalted hash is less secure though. :\
The whole point of a salted hash is to make it less attackable by rainbow tables. But then again sending the salt with the hash might just make that a moot point.
I suppose using the username as a salt might help a little.

-=-=-
Afr0 Games

Project Dollhouse on Github - Please fork!
Tue, 18 Oct 2011, 04:47
Afr0
--- What are you making, by the way? It sounds exciting!


I'm still working on TSO-R. Right now the plan is (in order of importance):

  • Authentication
  • Add more stuff to the GUI (city-selector dialog)
  • Fix GUI (textboxes)
  • Add mesh-rendering code (this has limited priority because my understanding of it is so small)

  • By now I've been thinking a lot about this (I've been in Rome for a week), and realized that there's no way of actually salting a hash without sending the salt used from the client to the server or vice versa in addition to the salted hash.
    Therefore I'm going to use the username as a salt. Hopefully this will prove effective enough to stop most rainbow-table attacks.

    Interception: a malicious user may not know the original password, but if they can intercept the hash, they can authenticate using that directly. (This also applies to session hashes).


    How do you propose I prevent this? The connection isn't actually encrypted until the hashed password has been sent to the server so that it can be verified and the unhashed password used as a shared key for encryption and decryption (ARC4)...

    -=-=-
    Afr0 Games

    Project Dollhouse on Github - Please fork!