Is it an good idea of Using password itself as an salt
Asked Answered
S

2

7

I have read in many articles that we should combine an unique salt to each passwords before hashing and store the salt in database for verification but How about using the password itself as an salt ?

Doing this will benefit as the salt will be unique for each as well as it will be hidden as it will be stored no where.

An simple example I can give for above is:

$hashToStore=sha1(strrev($password).$password);

Above I am just reversing the password and using it as an salt (I will be doing something more complex then just reversing it in development.)

Is This an better way for storing passwords or will be a bad practice.

PS:I am completely aware of php latest inbuilt functions such as crypt() and use it in real world, but yet wanted an review for above.

Snifter answered 25/6, 2014 at 18:29 Comment(10)
If two people have the same password then that salt isn't exactly unique now is it?Symposium
No that is awful. Don't do it. The salt should be random. Also sha1 is terrible for password hashing.Tetrode
The verdict just use: php.net/manual/en/function.password-hash.phpTetrode
@Dismissile-Yes but it wont give hacker a way in or will it ?Snifter
The main motive of mine was of escaping from storing salts.Snifter
#24416450Tetrode
@Subhanker Their encrypted passwords will be the exact same, so it gives them too much info.Symposium
@Symposium s/encrypted/hashedTetrode
FOR THE LOVE OF TURING, JUST USE PASSWORD_HASH!!Shanonshanta
If you were to do that, how long will it take me to create a dictionary? The whole purpose of hashing would be lost.Cristycriswell
P
8

A common mistake is to use the same salt in each hash. Either the salt is hard-coded into the program, or is generated randomly once. This is ineffective because if two users have the same password, they'll still have the same hash. An attacker can still use a reverse lookup table attack to run a dictionary attack on every hash at the same time. They just have to apply the salt to each password guess before they hash it. If the salt is hard-coded into a popular product, lookup tables and rainbow tables can be built for that salt, to make it easier to crack hashes generated by the product.

A new random salt must be generated each time a user creates an account or changes their password.


[…] It's easy to get carried away and try to combine different hash functions, hoping that the result will be more secure. In practice, though, there is very little benefit to doing it. All it does is create interoperability problems, and can sometimes even make the hashes less secure. Never try to invent your own crypto, always use a standard that has been designed by experts. Some will argue that using multiple hash functions makes the process of computing the hash slower, so cracking is slower, but there's a better way to make the cracking process slower as we'll see later.

Here are some examples of poor wacky hash functions I've seen suggested in forums on the internet.

md5(sha1(password))
md5(md5(salt) + md5(password))
sha1(sha1(password))
sha1(str_rot13(password + salt))
md5(sha1(md5(md5(password) + sha1(password)) + md5(password)))

Do not use any of these.


Salt should be generated using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). CSPRNGs are very different than ordinary pseudo-random number generators, like the "C" language's rand() function. As the name suggests, CSPRNGs are designed to be cryptographically secure, meaning they provide a high level of randomness and are completely unpredictable. We don't want our salts to be predictable, so we must use a CSPRNG. The following table lists some CSPRNGs that exist for some popular programming platforms. (PHP: mcrypt_create_iv, openssl_random_pseudo_bytes)

The salt needs to be unique per-user per-password. Every time a user creates an account or changes their password, the password should be hashed using a new random salt. Never reuse a salt. The salt also needs to be long, so that there are many possible salts. As a rule of thumb, make your salt is at least as long as the hash function's output. The salt should be stored in the user account table alongside the hash.

To Store a Password

  1. Generate a long random salt using a CSPRNG.
  2. Prepend the salt to the password and hash it with a standard cryptographic hash function such as SHA256.
  3. Save both the salt and the hash in the user's database record.

To Validate a Password

  1. Retrieve the user's salt and hash from the database.
  2. Prepend the salt to the given password and hash it using the same hash function.
  3. Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.

At the bottom of this page, there are implementations of salted password hashing in PHP, C#, Java, and Ruby.

In a Web Application, always hash on the server

If you are writing a web application, you might wonder where to hash. Should the password be hashed in the user's browser with JavaScript, or should it be sent to the server "in the clear" and hashed there?

Even if you are hashing the user's passwords in JavaScript, you still have to hash the hashes on the server. Consider a website that hashes users' passwords in the user's browser without hashing the hashes on the server. To authenticate a user, this website will accept a hash from the browser and check if that hash exactly matches the one in the database. This seems more secure than just hashing on the server, since the users' passwords are never sent to the server, but it's not.

The problem is that the client-side hash logically becomes the user's password. All the user needs to do to authenticate is tell the server the hash of their password. If a bad guy got a user's hash they could use it to authenticate to the server, without knowing the user's password! So, if the bad guy somehow steals the database of hashes from this hypothetical website, they'll have immediate access to everyone's accounts without having to guess any passwords.

This isn't to say that you shouldn't hash in the browser, but if you do, you absolutely have to hash on the server too. Hashing in the browser is certainly a good idea, but consider the following points for your implementation:

  • Client-side password hashing is not a substitute for HTTPS (SSL/TLS). If the connection between the browser and the server is insecure, a man-in-the-middle can modify the JavaScript code as it is downloaded to remove the hashing functionality and get the user's password.

  • Some web browsers don't support JavaScript, and some users disable JavaScript in their browser. So for maximum compatibility, your app should detect whether or not the browser supports JavaScript and emulate the client-side hash on the server if it doesn't.

  • You need to salt the client-side hashes too. The obvious solution is to make the client-side script ask the server for the user's salt. Don't do that, because it lets the bad guys check if a username is valid without knowing the password. Since you're hashing and salting (with a good salt) on the server too, it's OK to use the username (or email) concatenated with a site-specific string (e.g. domain name) as the client-side salt.

source: https://crackstation.net/hashing-security.htm

So, to answer your question, bad idea, very bad idea.

Platitudinize answered 25/6, 2014 at 18:38 Comment(4)
Very well written with good citations - keep it up. I really think the best idea though would be to recommend the new password_hash API, it really abstracts having to think about this thing from most developers. You can use it with older PHP too.Hedonic
The article you linked too is good, but what's the point of copypasting it here?Simonetta
@thg435 answers should always include the important parts of the linked source, because we want the answer to be valid even if the other site moves or removes the linked document. (See "Provide Context for Links" in the help (stackoverflow.com/help/how-to-answer)Firedrake
@Gus: linking and citing is fine, copypasting large chunks of external text is not.Simonetta
P
0

Please, don't ever do this. The whole point of salting is that every persons password hash will be unique which removed the issues of rainbow tables and giving away who has the same password.

Why does that matter? Look at the LinkedIn hack where they had "password hints". People has hints like "rhymes with assword" which gave away what their password, and also their hash was. It also gave away EVERYONE ELSE who was using the same password.

Patsypatt answered 25/6, 2014 at 18:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.