Password Salting

tdktank59

Gawd
Joined
Jan 23, 2007
Messages
590
So im building a authentication library for a site im working on.
There are other reasons besides the fact that im reinventing the wheel so don't get started there...

Back on topic...

The way I understand it is salt basically makes a pre-compiled rainbow table useless since you have no introduced yet more characters into the hash.

So a normal rainbow table would have
foo == acbd18db4cc2f85cedef654fccc4a4d8

And lets say I have a user
Username: Bob
Password: foo
Salt: asdf
encypted pass: ba6cd6a1511681f0df6d455f41d49ebc

And the user dosn't know how im storing the password (in this case password+salt)

As you can see ba6cd6a1511681f0df6d455f41d49ebc != acbd18db4cc2f85cedef654fccc4a4d8

So I guess all a salt does it make the rainbow table worthless and the fact that they would have to now generate a new one with the users salt. Just means It would take longer to crack 1 users password.

However it would make it closer to a brute force since each user has their own salt.

==================

So now the next thing is with some fancy programming (not really but more fancy than md5(password.salt); )

Why not add some more complexity since id be storing the password and salt in the table right next to each other.

Say we have the salt of asdf1234

Now instead of just md5(password+salt) lets do
md5((first 4 of salt) + password + (last 4 of salt))

This adds even more complexity to the script in the sense that if they just took the database they have no clue now that you split the salt. And to top that off you could encrypt the code as well to hide this fact a bit more as well.

Guess this was more of a just making sure I am getting what password salting is used for. It has always confused me that you store the salt with the password.
 
Now instead of just md5(password+salt) lets do
md5((first 4 of salt) + password + (last 4 of salt))
Adding complexity doesn't really add much, but you can do it if you want. As you guess, the purpose of the salt is to protect the user's passwords if the database is compromised. Even if the salt and the password hash are known, a rainbow table isn't useful and must be generated from scratch for each password to be guessed.

Ideally your salt is random, it is fairly common to generate the salt like md5(time() . $userip) or something similar. This will ensure you don't have any duplicate salts and make them pseudorandom and long enough to make a difference.
 
There are other reasons besides the fact that im reinventing the wheel so don't get started there...
Huh?

The way I understand it is salt basically makes a pre-compiled rainbow table useless since you have no introduced yet more characters into the hash.
Yes, that's the point.

So I guess all a salt does it make the rainbow table worthless and the fact that they would have to now generate a new one with the users salt. Just means It would take longer to crack 1 users password.
Yes.

However it would make it closer to a brute force since each user has their own salt.
I can't understand you, mainly because "it" has no clear antecedent.

Guess this was more of a just making sure I am getting what password salting is used for. It has always confused me that you store the salt with the password.
If you don't store the salt with the password, you have no way to test for password matches.
Ideally your salt is random, it is fairly common to generate the salt like md5(time() . $userip) or something similar. This will ensure you don't have any duplicate salts and make them pseudorandom and long enough to make a difference.

There's nothing random about your suggested seed. Since it's predictable and externally observable, it's easy to attack.
 
The salt should be something dynamically generated for that particular user. Obviously you don't want a column in the database called 'salt', or anything obvious like that. You can use characters in the user's password as a salt, as well as columns such as numerical ID's, etc. It is also a good idea to re-hash more than once, with a little variance, such as re-hashing once for each character in the user's password.

If you do things like this the hash in the database will be pretty much useless unless the attacker was also able to obtain your code.
 
Why not? The salt is not a secret.

The salt does not have to be secret, but it is generally good practice to use a derived value, and not a stored value. Either way, a salt renders rainbow tables useless and makes brute forcing pretty pointless, but at least with a derived salt the hacker might waste some of their own time thinking the hash is unsalted. Obviously, the less information you hand over to a hacker, the safer you are.
 
but at least with a derived salt the hacker might waste some of their own time thinking the hash is unsalted.
Please elaborate. Whether the salt is derived or stored has no impact on the appearance of the hash.

In fact, I would argue that stored salts are implicitly more secure than derived salts simply because derived salts, while making brute-forcing more difficult, are still subject to brute force.
 
Please elaborate. Whether the salt is derived or stored has no impact on the appearance of the hash.

If someone was to obtain a copy of the database and they see a column called 'salt' I think it's pretty obvious to them that the password hash is salted. Either that or they just stole the db of a recipe site ;)


In fact, I would argue that stored salts are implicitly more secure than derived salts simply because derived salts, while making brute-forcing more difficult, are still subject to brute force.

If you look at my original post I actually suggested a combination of stored and derived values to generate the salt. I just stated that you shouldn't use an obvious column called 'salt'. Your point is completely valid though.
 
There's nothing random about your suggested seed. Since it's predictable and externally observable, it's easy to attack.

Not necessarily. The time at which the salt is created is not known, nor the account's registered IP address, making the salt a little bit more intense to try to crack.
 
Not necessarily. The time at which the salt is created is not known, nor the account's registered IP address, making the salt a little bit more intense to try to crack.

You still have to store the salt if you want to decrypt the password (or verify that what someone enters matches what they previously entered). (the time of day changes... and so do clients' IP address).

Take a step back and consider what's a more secure salt: Something nobody else knows (something you generate) or something that "almost" nobody else knows (Time/IP)?
 
Last edited:
You still have to store the salt if you want to decrypt the password. (afterall, the time of day changes... and so do clients IP address).

Take a step back and consider what's a more secure salt: Something nobody else knows (something you generate) or something that "almost" nobody else knows (Time/IP)?

I'm not disagreeing, just pointing out. I'm also definitely not saying to not store the salt somewhere, otherwise the entire point of salting is defeated.

A time dependent salt is still dynamic enough to make unique salts for each separate user. It also makes brute force attacks limited to one user at a time (in general).
 
Never make a password decryptable...

The point im trying to make is instead of just doing

md5(salt+password)

do something more like

md5(salt(1,4)+password+salt(5,8))
where salt(1,4) means start at the first go to the 4th...

Putting some of the salt process into the code, Making it substantially harder to crack the password if only the salt and the password are known.

However if they get the code then its the same as salt+password... Just adds one more thing for them to have to fight...


As to the time and IP method... I store when my users were created, updated etc... And I log their IPs to watch for multiple accounts.
So all this stuff would be in my system. Yet adding more complexity to the password process... Meaning they would now NEED the code to figure out what im throwing into the password.


From what ive figured out all salting does is it makes it insanely harder to brute force an entire database or even a record because they have to regenerate the rainbow table. However it only protects you if all they steal is the database. However if they take the code as well they can figure out where and how the salt is being used.
 
From what ive figured out all salting does is it makes it insanely harder to brute force an entire database or even a record because they have to regenerate the rainbow table. However it only protects you if all they steal is the database. However if they take the code as well they can figure out where and how the salt is being used.

Yes, we can always assume that the attacker can brute-force the passwords (or at least find a hash collision). Salting makes it so that each stored password must be brute-forced individually, assuming the salts are unique and non-trivial. If the DB is compromised and contains 10,000 user's passwords, they can't just run it through a rainbow table and get a lot of hits, they will have to manually generate new (and not use standard) rainbow tables for each user, which is probably intractable for most attackers. The method of how the salt is generated is not cryptographically secure, so we can assume it's easy to attack. If this is a public site the user can create test accounts with known passwords and discover the method relatively easily compared to attacking the passwords themselves, and if they compromised the database, getting the sourcecode for the site is likely easy as well. It's generally assumed that the attacker knows the salt. It just needs to be unique.

There's nothing random about your suggested seed. Since it's predictable and externally observable, it's easy to attack.
Yeah, you're right. I was trying to say that it would generate long strings that appear random, making rainbow tables intractable, and that it was common to generate the salt rather than store it specifically. However building a rainbow table using guessed salts would be possible, so it's probably best to just forget that and store a randomly generated (unique) salt.
 
The point im trying to make is instead of just doing

md5(salt+password)

do something more like

md5(salt(1,4)+password+salt(5,8))
where salt(1,4) means start at the first go to the 4th...

Putting some of the salt process into the code, Making it substantially harder to crack the password if only the salt and the password are known.
What you're describing is merely security through obscurity, which never works. Always assume an attacker knows exactly how your cryptosystem works....because they probably do. keenan's argument about storing the salt in a column not named "salt" is the same thing. Not to mention that it's subject to problems if the columns it's derived from change.
 
What do you mean by "now"? To realize what goal? I guess I'm confused by your statement, but I'm also unaware of what it is exactly that the original poster is trying to secure or prevent.
 
I hear this a lot, but I don't believe it. Most security systems are based on obscurity at some level.

There's a big difference between an 'obscure' key and security through obscurity. The general opinion among security experts is that openness is important since errors are easy to miss and easy to create. Cryptosystems are subject to intense scrutiny before they're used in any serious fashion, and that's important - 'independently designed' cryptosystems tend to be quickly broken.

The other problem is that security through obscurity relies on a secret that is hard to keep secret since it's coupled to the operation of the system, and once it's exposed, the whole house of cards falls down and the system itself is entirely broken and can't be used anymore, anywhere. A crypto key being exposed only affects one implementation of the system, and changing or revoking the key restores the security of the system. ie. a general attack is much more difficult.

Since the attack against the obscurity is so trivial in comparison, and since you need the 'real' security anyway, the 'obscurity' often just makes things more complicated and error prone, rather than providing any real benefit. Though it doesn't really hurt either.
 
What do you mean by "now"? To realize what goal? I guess I'm confused by your statement, but I'm also unaware of what it is exactly that the original poster is trying to secure or prevent.

??? He's saying, in context, that if they compromised the system they would need to take both at that point rather than have the database be useful on its own.... (I'm just saying what he said, I don't necessarily agree/disagree).
 
??? He's saying, in context, that if they compromised the system they would need to take both at that point rather than have the database be useful on its own.... (I'm just saying what he said, I don't necessarily agree/disagree).

Problem is, they had to do that "Before", as well -- assuming "before" is "before the salt was added to the database". The password hash algorithm is arbitrary, and stored only in the code. If a black hat has the database, they have only the hashes and don't know the algorithm to get from their dictionary to the hashes, or from the hashes back to plain text.

Since "now" is no different than "before", he must mean something different by "now", right?
 
Back
Top