Should the Salt for a password Hash be "hashed" also? - security

This I think may be a silly question, but I have become quite confused on what I should do here for the best.
When salting a password hash, should the salt also be hashed or left as plaintext?
NOTE: I am hashing a password in SHA-256 and the Salt is a pre defined string as only one password will ever be stored at a time.
TIA
Chris (Shamballa).

It doesn't matter.
The purpose of a salt is to prevent pre-computation attacks.
Either way, hashing the salt or using it by itself, results in the same data being added as a salt each time. If you hash the salt, all you are effectively doing is changing the salt. By hashing it first, you convert it into a different string, which is then used as the salt. There is no reason to do this, but it will not do anything wrong if you do.
You just need to be consistent and use the same method every time or you will end up with a different password hash.

You must not hash the salt, since hashes are one way. You need the salt so that you can add it to the password before hashing. You could encrypt it, but it's not necessary.
The critical thing about salts is that each password should have its own salt. Ideally, each salt should be unique, but random is good too. The salt should therefore be long enough to allow it to be unique for each password.
If all salts are the same, it's obvious to the cracker (who can see your hash values), which accounts have the same password. The hash values will be the same. This means that if they crack one password, they get more than one account with no additional work. The cracker might even target those accounts.
You should assume that the cracker will gain both the salt and the hash value, so the hash algorithm must be secure.
Having any salt at all prevents using existing precomputed rainbow tables to crack your hash value, and having a unique salt for each account removes the desire for your cracker to precompute their own rainbow tables using your salt.

The salt should not be hashed, as you need the original value to combine with the password before hashing it.

No you must not hash the salt. The salt is in clear text and it is needed to you to recompute the password and check it with the one stored in the hashed password file.
But if you need a strong salting procedure you can compute your salted password in this manner:
SaltedHashedPwd = H(H(H(H(.....H(PWD-k+SALT-k)+SALT-k)+SALT-k).....)+SALT-k+N
H is the hash function
SALT-k is a k-random string you use as salt
PWD-k is the k-password
(every Password has a different salt)
N is the iterations number you compose the H function
In the PKCS#5 standard it uses N=1000!
In this manne a Dictionary attack is not possible because for every word into the Dictionary and for every SALT into the password file, the attacker needs to compute the Hash. Too expansive in time!
I think that N=100 should be enough for your uses :-)

As the salt needs to be saved along with the hash (or at least must be retrievable along with the hash), an attacker could possibly get both the salt and the hashed password. In some of my applications, I've stored the salt encrypted in the database (with a key known only to the application). My reasoning was that storing the salt unencrypted along with the hashed password would make it easier to crack the passwords, as a hacker that would be able to retrieve the password table (and would know or make an assumption about the hash algorithm) would be able to find matches between hashes of well known words (dictionary attack) by hashing each word in the dictionary and then salting with the salt he also has access to. If the salt would be encrypted, such an attack wouldn't be possible unless he would also have access to the encryption key known to the application.
(If anybody sees a fault in this logic, please comment.)

Related

Salted Hash Password Authentication

I've been reading up on OWASP 10 and I came across the best practice to store information.
Salted hashing. Where you generate one random salt for every password and combing it and hash it and store it.
My doubt is, if the salt is generated randomly how the password be authenticated when the user types it?
Is the salt saved along with the user name?
If so, this practice is still vulnerable.
OR how do they do it?
The salt is saved along with the user name. Salts are not secret. The point of a salt is to ensure that if two people have the same password, they won't have the same hashed password. This prevents pre-computed hash attacks (rainbow tables), and prevents leaking that two users in a database have the same password.
While per-user random salts are ideal, the benefits of salting can also be achieved with deterministic, but unique, salts. For example, you can use some fixed string for your database and join that with the userid (com.example.mygreatsystem:user1#example.com) and use that as the salt. Since it's unique to every user (not just within this system, but globally), it achieves the same goals as a random salt without requiring an extra database lookup. Like with random salts, this scheme does not need to be secret. The important part of a salt is it be unique. But when practical, a per-user random salt of sufficient length (typically 8 random bytes), stored with the user record, is best practice.

Salting with an intrinsic property of the password

From Wikipedia on Salt (cryptography):
A new salt is randomly generated for each password. In a typical setting, the salt and the password are concatenated and processed with a cryptographic hash function, and the resulting output (but not the original password) is stored with the salt in a database.
But what if I don't have a discrete database? Is it okay to salt with an intrinsic property of the password, such as its reverse? Or even (better?) salting a password with the hash of the password? For example:
md5(md5("password") + "password")
Of course there are performance consequences, but if I'm working with a low-access system, would this kind of salting display any vulnerabilities?
Again, the main reason I would look into doing this would be to save myself a lot of trouble storing a salt.
Since you have to store the hash of the password plus any salt somewhere (else, how would you have anything to compare to when it comes time to authenticate), why not store them together?
It's not uncommon to store both the salt and the hash result of the password and salt in a single field. They can be teased apart when needed by using salts with constant lengths, or by using a separator character that is not part of the set of characters used in your salt.
Would this kind of salting display any vulnerabilities?
Yes. A key purpose of the unique salt is to ensure that users who select the same password will have different password hashes. If the salt is calculated as a function of the password, then users who share the same password will also share the same password hash.
With a database of hashes, an attacker can simply find hashes that appear multiple times. Such passwords are likely to be weak and attractive targets for a brute-force attack.
If you must store passwords and cannot store a dedicated salt, a better approach would be to use an invariant field associated with the account (e.g., username or account identifier) as the salt. This approach will protect against duplicate password hashes in your database.

Why does salting a hashed password increase security?

I've been doing some research about securely storing passwords in a database. It is generally suggested that you use a salt. As explained in one of the answers in Secure hash and salt for PHP passwords, this changes the value of hashes, making a password more difficult to compromise.
As part of the verification mechanism, the password entered by the user is combined with the salt and hashed as needed. Given that the salt is transparent to the user, how does using salt provide any added benefit?
As I see it, with or without hashing, the same password will successfully authenticate you, because the plumbing that makes it different will take place behind the scenes. That is why none of the articles I've read so far have clarified things.
consider a scenario, where you accept a password from you user and you are sending it over network or storing in database as plain-text.
if your user enters a password say 6-8 characters long. A hacker may have pre-generate hashes for all possible strings of 6-8 characters length and he can possibly deduce the password, by comparing it with your hash.(Matching your hash against all the pre-generates hashes, he can get a set of possible candidates,if collision occurs)
But if you append a salt of say 30 chracters to his plain-text password and then hash it. it becomes very difficult for any hacker to pre-generate all the possible combinations of that range. That is the main reason why we use a salt.
You cant restrict every user to input a 30 character long password for security purposes. if any user chooses a 4 char length password, just add 30 char salt and make it more secure.
Salted passwords reduce the probability that a rainbow table will already have the salted password's hash contained in it.

How can bcrypt have built-in salts?

Coda Hale's article "How To Safely Store a Password" claims that:
bcrypt has salts built-in to prevent rainbow table attacks.
He cites this paper, which says that in OpenBSD's implementation of bcrypt:
OpenBSD generates the 128-bit bcrypt salt from an arcfour
(arc4random(3)) key stream, seeded with random data the kernel
collects from device timings.
I don't understand how this can work. In my conception of a salt:
It needs to be different for each stored password, so that a separate rainbow table would have to be generated for each
It needs to be stored somewhere so that it's repeatable: when a user tries to log in, we take their password attempt, repeat the same salt-and-hash procedure we did when we originally stored their password, and compare
When I'm using Devise (a Rails login manager) with bcrypt, there is no salt column in the database, so I'm confused. If the salt is random and not stored anywhere, how can we reliably repeat the hashing process?
In short, how can bcrypt have built-in salts?
This is bcrypt:
Generate a random salt. A "cost" factor has been pre-configured. Collect a password.
Derive an encryption key from the password using the salt and cost factor. Use it to encrypt a well-known string. Store the cost, salt, and cipher text. Because these three elements have a known length, it's easy to concatenate them and store them in a single field, yet be able to split them apart later.
When someone tries to authenticate, retrieve the stored cost and salt. Derive a key from the input password, cost and salt. Encrypt the same well-known string. If the generated cipher text matches the stored cipher text, the password is a match.
Bcrypt operates in a very similar manner to more traditional schemes based on algorithms like PBKDF2. The main difference is its use of a derived key to encrypt known plain text; other schemes (reasonably) assume the key derivation function is irreversible, and store the derived key directly.
Stored in the database, a bcrypt "hash" might look something like this:
$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
This is actually three fields, delimited by "$":
2a identifies the bcrypt algorithm version that was used.
10 is the cost factor; 210 iterations of the key derivation function are used (which is not enough, by the way. I'd recommend a cost of 12 or more.)
vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa is the salt and the cipher text, concatenated and encoded in a modified Base-64. The first 22 characters decode to a 16-byte value for the salt. The remaining characters are cipher text to be compared for authentication.
This example is taken from the documentation for Coda Hale's ruby implementation.
I believe that phrase should have been worded as follows:
bcrypt has salts built into the generated hashes to prevent rainbow table attacks.
The bcrypt utility itself does not appear to maintain a list of salts. Rather, salts are generated randomly and appended to the output of the function so that they are remembered later on (according to the Java implementation of bcrypt). Put another way, the "hash" generated by bcrypt is not just the hash. Rather, it is the hash and the salt concatenated.
This is a simple terms...
Bcrypt does not have a database it stores the salt...
The salt is added to the hash in base64 format....
The question is how does bcrypt verifies the password when it has no database...?
What bcrypt does is that it extract the salt from the password hash... Use the salt extracted to encrypt the plain password and compares the new hash with the old hash to see if they are the same...
To make things even more clearer,
Registeration/Login direction ->
The password + salt is encrypted with a key generated from the: cost, salt and the password. we call that encrypted value the cipher text. then we attach the salt to this value and encoding it using base64. attaching the cost to it and this is the produced string from bcrypt:
$2a$COST$BASE64
This value is stored eventually.
What the attacker would need to do in order to find the password ? (other direction <- )
In case the attacker got control over the DB, the attacker will decode easily the base64 value, and then he will be able to see the salt. the salt is not secret. though it is random.
Then he will need to decrypt the cipher text.
What is more important : There is no hashing in this process, rather CPU expensive encryption - decryption. thus rainbow tables are less relevant here.
Lets imagine a table that has 1 hashed password. If hacker gets access he would know the salt but he will have to calculate a big list for all the common passwords and compare after each calculation. This will take time and he would have only cracked 1 password.
Imagine a second hashed password in the same table. The salt is visible but the same above calculation needs to happen again to crack this one too because the salts are different.
If no random salts were used, it would have been much easier, why? If we use simple hashing we can just generate hashes for common passwords 1 single time (rainbow table) and just do a simple table search, or simple file search between the db table hashes and our pre-calculated hashes to find the plain passwords.

How would you add salt to your existing password hashes?

I have a database of hashed passwords that had no salt added before they were hashed. I want to add salt to new passwords. Obviously I can't re-hash the existing ones.
How would you migrate to a new hashing system?
Sure you can. Just add a salt to the existing hash and hash it again. Of course this will require any future logins to go through the same process meaning two hash functions will need to be called but lots of legitimate patterns do this anyway so it doesn't smell as bad as you might think.
Salting a password is an effort to defend against rainbow tables. In this case the salt does not need to be a secret.
http://en.wikipedia.org/wiki/Rainbow_tables#Defense_against_rainbow_tables
You can actually see in the article
hash = MD5 (MD5 (password) . salt)
Which is the same exact method you would be using. (Except a different hashing function.)
As a quick fix, you could create a salt column in the database, and when a user logs in correctly matching the old hash, you can then use that password that they entered with a salt and create a new hash.
You could add a column, consisting of a flag showing whether the user has an old (no salt) or a new (with salt) hash.
A good idea is, at that point, to force all users to change their passwords upon sign in. This way you can get rid of that column eventually.
I dealt with a similar issue involving multiple hashing techniques. I used the approach of encoding a hash method type in the database as well (i.e. 'alpha', 'beta', 'gamma', 'delta'). I marked all current hashes with the appropriate level. As users logged in, I validated their passwords and re-hashed them using the updated methods. Our passwords expire after 90 days, so it was just a matter of holding on for 3 months until all passwords using the old methods could be reset.
There are some ways here that may work for you.
Remember, any constant pattern you add into the existing hash is useless (one of the tricks on that link is suggesting something like that). There should be no identifiable pattern that can be used to isolate the salt.
Of course, the best way would be to migrate to a salted hash table.
Create a new field in you're database named "salted" with a type of true/false (or whatever the equivalent is in your DBMS). Set all the values to false for the existing hashes. Whenever a new, salted, hash is added, set the "salted" field to true.
Then, all you have to do is handle the two types of hashes differently in your code.
This is more of a general solution than a specific one, but it should solve your problem.
If you are storing the salt inside the hash, it should be fairly straight forward to determine if a salt is included by checking the length of the hash. If there isn't a salt, just hash the password, if there is a salt, hash the password + salt.
You shouldn't need a boolean column in your database.
The best way I store my salt is that I embed the salt value within the password hash + salt I have just created. I don't append the salt string to the beginning or end of the hash, I literally embed the salt into the hash.

Resources