views:

1561

answers:

8

I was doing a little research or googling for different methods of handling password hashing and salting and came across this interesting link:

http://phix.me/salt/

Now, essentially what this proposes is the creation of two user functions, one for hashing and one for checking the hash.

The salt is pseudo random but is in actual fact based upon the password (strikes me as bad?).

The hashing function also pseudo randomly "sprinkles" the salt amongst the hash string.

The hash checking function reverses the salt sprinkling and then the actual hash check takes place.

Now, I'm aware that unique salts for each password hash = good, but also that having the logic to hash the passwords and create the salt stored in a db function might = bad.

I like the idea that the salt isn't obvious and that it also needn't be based on some hopefully consistent value such as username, userid, date of birth etc, but as I said I do have my doubts as to the implementation.

So, what are people's opinions and ideas of "best approach solutions"?

+4  A: 

(Edited answer because I misread the article initially and thought he was just mixing the salt together with an unsalted hash)

His techniques do seem fine, they'll work, but they're not really any "better" than normal salting methods. It's just an attempt to do security by obscurity, it's no better than making up your own random "hash scrambling" method and hoping that the attacker doesn't figure it out.

In fact, it could actually be quite easy for the attacker to figure these functions out, in many cases. If the site is one with public registration, the attacker could repeatedly register accounts with known passwords, then use the known md5 hashes for those passwords to reverse-engineer the password scrambling algorithm. I'd be able to do this very easily, even looking at the result of his "Attempt 4".

If you want to store your passwords really securely, get away from MD5 and even SHA1, and move towards a salted, slower hash function. This is a great article about the topic: Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes

Chad Birch
Oh wow, I hadn't even noticed that! Certainly casts doubt on the validity of his approach.
BrynJ
Ding down. Attempt 1 was spot on, and his later attempts are what missed the point.
Jeffrey Hantin
Ah, I did misread, he is appending it before he does the hash as well. So yes, it's functional, but it's still not some "amazing" new method to do salting, it's really no better than doing it the normal way.
Chad Birch
The key is that both the password and the salt were input to the hash, and the salt was also stored next to it. Weaknesses in MD5 probably aren't the end of the world for password tables, but it's easy to swap out a hash function.
Jeffrey Hantin
Indeed. If I could sum up this answer (and make it "the" answer), I would say this: Attempt 4 obfuscates a solution that is already cryptographically sound. Replace MD5 with SHA256 or bcrypt and the scheme is secure pending "major advances in cryptography."
Peter J
Well, much too frequently these kind of kind of obfuscation attempts end up in schemes that are much worse than the plain schemes. So it is quite understandable that you expected some mistake here.
Accipitridae
@chad birch: great point about creating accounts with known passwords. but wouldn't that only work for the cracker if he had already compromised the database and could see the hashes for each of his created accounts?
42
@42: Yes, but that's the point. The only reason anyone would be trying to reverse-engineer this algorithm in the first place is if they need to understand the hashes that they have access to.
Chad Birch
+4  A: 

There have been many similar questions asked before:

That should get you an idea of how to hash passwords.

musicfreak
+3  A: 

This seems for me to just add obfuscation, not any more security, to the (as Chad Birch pointed out misunderstood) salted hash method.

Karsten
+7  A: 

The purpose of a salt is to make the use of a rainbow table prohibitively expensive, so Attempt 1 pretty much solves the problem correctly. Basing the salt on the password eliminates the variability that defeats rainbow tables, and trying to hide it in the hashed password field is just pointless.

Jeffrey Hantin
You were right about my initial answer, Jeffrey, thanks. In my skimming, I had misread his select statement as "concat(md5(concat('password')),@s);", so I thought that all he was doing was concatenating the salt onto the end of an unsalted hash. He does salt it properly though, the rest of the techniques in the article are just pointless security-by-obscurity wankery.
Chad Birch
Oh dear, I made the same mistake too.
BrynJ
Yup, that is an accurate analysis of the situation. The proposed scheme adds complexity but not security.
Accipitridae
+6  A: 

The salt doesn't need to be secret. It does need to be unpredictable for a given password.

Deriving the salt from the password completely misses the point.

erickson
+1 +1 +1. A salt should never be *based* on the password.
Randolpho
Is it feasible to use the username as a salt? Seems like the goal of exponentially increasing the rainbow table size is met.
Peter J
@Iconic: Interesting question. I'd say it's probably not the best idea. A salt should be unique PER PASSWORD, and that includes any passwords in the password history. Using the username as the salt violates that principle.
Randolpho
I agree; while deriving the salt from the username (or other user information) isn't terrible, it could make some sorts of attacks easier. If I'm interested in trying to crack the passwords of a user with the same name on different sites, and each site used the user name as the salt, it might be worthwhile for me to create a dictionary. When choosing a random salt from a cryptographic RNG works so well, and is so easy, why mess with anything else?
erickson
If the various sites don't derive the salt from the username in the same way, exactly how is the dictionary going to work?
Seun Osewa
There are a lot of sites that use the exact same implementation for password hashing. For example, all sites that use the built-in Tomcat password authentication. But you are right, if a site makes even a small change in derivation, the dictionary will be worthless.
erickson
+4  A: 

I asked a similar question earlier. The consensus was this:

It doesn't matter how you salt, so long as you:

  1. Salt before you hash
  2. Use a random salt unique per password
  3. Use a large enough salt to make rainbow tables prohibitive.

You can even store your salt right next to your hashed passwords and feel pretty darn confident.

Personally, I find GUIDs (in string format) work great for Salts. They take a line of code to generate and in string format are more than large enough to make rainbow tables take millennia to compute.

Randolpho
Good tips, Randolpho. I would add use of a key stretching technique, such as iteratively hashing several thousand times. A good salt defeats rainbow tables, but you need key stretching to slow brute-force search of the "bad password space" (7 or 8 character passwords).
erickson
@erickson: That might work but it looks computationally expensive for the server.
Randolpho
It adds a milliseconds to the authentication of each legitimate user, so in most real applications, it's negligible. It only adds up to something "expensive" when making millions of attempts in an offline cracker. *Without it,* one can search a 7 character space in a few days (if the salt is not secret, which is the safe assumption). This assumes a single machine with a nice graphics card; if you are willing to spend a little money, you can search an 8 or 9 character space. If you are willing to spend a lot of money (think big government)... well, key stretching is imperative.
erickson
Hmm... Well, I'll certainly do some research into key stretching, if you really think the performance is negligible.
Randolpho
is there any consensus regarding storing the unique salt with the user's hashed password?
42
using GUIDs seems like an intriguing and simple approach.
42
+1  A: 

Interestingly, this is not just obfuscation, not any more security but actually obfuscation, less security because "Attempt 4" is only as good as the CRC32 function it uses (CRC32 is passed ONLY the password, not password+salt) - this is the downfall.

As per Chad's post, to crack "Attempt 4", all one has to do is CRC32 loads of passwords and then reverse the function he's coded up, leaving you with a salted md5 hash and the salt (which you would then test for validity). Simply test this pair by calculating md5(password+salt) (where password is the password you are trying) and salt is the salt you have calculated by reversing the algorithm. If the md5 equals the first 32 characters of the hash, you've cracked the password.

"Attempt 4" is worse than "Attempt 1", in some respects, as it as only as good as the worst function called in the entire routine, in this case, CRC32(password).

+1  A: 

I can't view the link in the original question (the website just returns a 404 not found error), but the method described in the question is not really using a salted hash.

In essence, this method is just using a non-standard hash: given a specific password, there is one unique value that will be stored in the database. This is all that is needed to make a rainbow tables attack work: I can precompute the hash value for a dictionary of likely passwords and look for any matches. Now, I will have to precompute rainbow tables specifically for this non-standard hash function.

In a proper implementation of salted hashes, when the passord is created, a random salt is combined with the password and hashed. Then random salt used and the hash are stored. Even if I know the password, I cannot predict what the hash will be since there will be a different hash for each of the many possible salt values. Now an attacker needs to precompute a rainbow table for each possible salt value: this takes a much larger effort.

Stephen C. Steel