What is the best way to securely store password (hashes) - security

A lot of websites these days are hacked and the password hashes are stolen.
Even big websites like LinkedIn didn't store their passwords secure (just md5).
Now is my question, what is a secure enough way to hash password?
Currently I'm using this:
sha512(sha512(sha512(password) + salt));
Is that secure enough?

hash_hmac('sha512', $data , $key);
would be great. It is better to use at least 60 chars for $key as salt.

It is hard to say which one is best, but a safe bet is the BCrypt algorithm.
BCrypt is not the best algorithm out there; however, it is sufficient for the large majority of use cases, and it is just as easy to implement, if not easier, than the basic hash-and-salt method. What sets BCrypt apart is that instead of the more typical SHA-* algorithm, it leverages the Blowfish algorithm, which has the advantage of being much slower in parallel. Since users log in one-at-a-time, this makes it much harder for attackers, who will test numerous passwords, to beat the algorithm.
More here: http://davismj.me/blog/bcrypt/

Yes, that's more than secure enough. Personally I think the last sha512 call is useless but I know opinions differ.
Of course, this is secure as long as passwords cannot be guessed using a brute force tactic. No amount of hashing will protect you if users choose a 4 letters password or the firstname of their wife.

It depends on your salt. Are you generating a unique salt for each user? A salt is not a constant, if every password is hashed with the same salt you're wasting your time.
I would recommend using bcrypt instead of the sha512/salt approach, it's much harder to brute force: http://krebsonsecurity.com/2012/06/how-companies-can-beef-up-password-security/

Using salt like you are using now is a really good to improve security, I highly recommend to use random salt for every user. IMHO, the more time you will hash user's password (you can improve security by adding salt before hashing each time) the more it will be secure. I use for loop with like 256 repetitions to hash password which may be considered to be secure against brute force for next bunch of years.
a little off topic, but I recommend to also take care about session hijack (like regenerating ssids, etc...)

Related

Importance of salt when using Rfc2898DeriveBytes to create secure passwords from clear text passwords

I'd like to incorporate the encryption and decryption of files in one of my C# .NET apps. The scenario is simple: User A sends an AES256-encrypted file to user B. The clear text password is exchanged on a different channel (e.g. phone call or whatever).
From what I understand I should use Rfc2898DeriveBytes for converting the user's clear text password into a more secure password using maybe 10,000 rounds. (see this article).
What I don't understand is the role of salt in my scenario. Usually salt is used in hashing passwords to prevent dictionary attacks. But in my scenario the PBKDF2 algo is used to compensate weaknesses of short or easy to guess clear text passwords by adding extra calculations required by the PBKDF2-rounds.
If I choose a random salt then the receiver will need to know that salt also in order to decrypt correctly. If I use a constant salt, then hackers can easily reverse engineer my code and run brute force attacks using my constant salt (although they'll be really slow thanks to the PBKDF2 iterations).
From what I understand I have no choice but to use a constant salt in my scenario and enforce a good clear text password rule to make up for the weakness of constant salt. Is my assumption correct?
Salts, in the context of password hashing (and key derivation), are used to prevent precomputation attacks like rainbow tables.
Note that the salt must be different and unpredictable (preferably random) for every password. Also note that salts need not be secret – that's what the password is for. You gain no security by keeping the salt secret.
The recommended approach in your case is to generate a random salt every time a file is encrypted, and transmit the salt along with the ciphertext.
Is there a specific reason you're using AES-256 by the way? It's around 40% slower than AES-128 due to the extra rounds, and it offers no practical security benefit (particularly not in the case of password-based encryption).
It's also worth considering using a well-established standard like PGP rather than building your own protocol from cryptographic primitives, because building secure protocols is so hard that even experts don't always get it right.
Your assumption is correct. If they have access to the password, they will also have access to the salt. The BCrypt implementations I've seen put the number of iterations, the hash, and the salt all in the same result string!
The idea is: your hash should be secure even if the salt and number if iterations is known. (If we could always know that the salt and number of iterations and even the algorithm would be unknown to attackers, security would get a whole heck of a lot easier! Until attackers politely decline to read our salts, we must assume they will have access to them in the event of a breach.) So you're right, they can brute force it - if they have a few supercomputers and a couple million years of computing time at their disposal.

Can I safely distribute a hashed password?

I have an application whose source code is checked into a public repository. This source code includes configuration files, and in those configuration files are SHA-256 hashed passwords.
My understanding is that when it comes to hashed passwords, an end user doesn't actually have to enter the password you used to generate the hash, but any password that generates the same hash value. I believe this is called a collision.
So can I display my hashed passwords in public with a reasonable assurance that someone can't take that hash and then generate a password (or generate a collection) that can be used to get access to my application? Is that a guarantee that these hashing algorithms try to make?
There are no known practical attacks against SHA-2 in the general case. It's generally considered better to keep hashed passwords secret, though, because there are rainbow tables, dictionary attacks, and other such things. If you took the proper precautions such as salting, round robin hashing, and having a nice long passphrase, it should be perfectly safe.
It's still better to not do this, though. You never know what cryptographic attacks might be developed in the future.
It is not likely for someone to reverse a HASH, SHA1, SALT etc. There are some ways out there to reverse one, but if you think your at that much of a risk I'd use SHA1 and SALT for maximum security. Having a long password makes it difficult to reverse, but unless they are real seasoned coders, your not very like to be a victim of it.
Read up on the algorithms at Wikipedia...
SHA1: http://en.wikipedia.org/wiki/SHA-1
SALT: http://en.wikipedia.org/wiki/Salt_(cryptography)
Just use a unique password and you should be fine ;-)

Is it possible to harden aes encryption against brute force attack?

is there any way to harden aes encryption against brute force attack without strengthening password. I mean users generally choose easy passwords. I don't want to force users to choose more and more complicated password.(This is the correct solution but it is useless when they forget their passwords continuously, and they cannot use their password) They choose their passwords from uppercase, lowercase and digits. And password length is 8. I want to make it difficult to brute force attacking without changing these password properties.
EDIT: Password length is exactly 8. Less length is not acceptable. And one more question over replies, keeping encrypted text on memory (using salting and key stretching) is a security problem?
I'm tempted to say that: No, it is not possible. In order to make the brute force attack harder, you need more entropy.
That being said, you can actually make the guessing process slower if you do key stretching.
It's hard to comment on the problem without knowing the exact nature of how it's being used. (For e.g., can the password only be stored as 8 characters?).
That said, choosing a good salt makes brute forcing harder. Most passwords stolen today are the result of failure to implement proper salting.
For more security you can employ consistent hashing to shard the salt over a range of values.
If you want to secure your users against using passwords like "password", "12345678" or similar, then no there's no way to harden them.
You must be able to check if provided password matches the hash you have in reasonable time (that is, less than 1s on average hardware). Brute forcing simple passwords even when checking equality between hash and password takes 1s will take less than a day on an average PC.
If you want to secure average quality passwords (not in the top 1000 most common passwords or single words from few most commonly spoken languages), then password/key stretching is your best bet: scrypt, bcrypt or the standard PBKDF2 are good choices.
Using multiple rounds will slow down the process of trying out passwords but thats about all I can think of.

Storing salt+password hash in DB and protecting against password attack

Please help me with my understanding. Also I am not talking about SSL or DH key exchange.
As the salt is stored in DB and is a secret to the attacker to just protect the user original password (Rainbow tables), in case attacker gets their hand on the actual DB itself. Then how will how you protect against brute/dictionary based attacks. Once again, logging the wrong requests and denying IP of many bad request is known, I am talking about cryptography here. As the password is same for user1, attacker got it from other websites, how does salt protects here. I guess not, then what are the best solutions available to stop such attacks. Assume data is really important like credit card numbers + CVV(I know don't store CVV, but that is not the question).
EDIT: By the way, I came up with some stupid idea, and it looks like a known method for stopping dictionary attacks. Read more this question: High cost encryption but less cost decryption
May be we can discuss some other methods here, to protect against brute/dictionary/social engineering password attack
It's a little unclear to me what your actual question is, but if it is "How does a salt help protect me against brute force attacks?" the answer is that technically it does not. There is nothing about a salt that makes brute force attacks more difficult, salts instead make it difficult to brute force multiple accounts simultaneously. Essentially salts artificially inflate search space required to do a brute force attack, making it computationally difficult to pre-calculate every possible password and then check them against the entire database. Salts can be stored in the clear, so long as they are unique to each password.
If you want to make brute forcing passwords more difficult, what you want is an adaptive hashing scheme. These schemes allow you to dictate how long hashing should take. Because an honest client should only have to authenticate on the order of tens of times, but an attacker will need to do it on the order of millions or billions of times, slower hashes make the task near impossible for the attacker while introducing little overhead in the system.
What this all boils down to is that you should use bcrypt if you are hashing passwords. It is designed to incorporate a salt and is an adaptive hashing system. For more info, see this article on security.stackexchange.com
About salt : If you search the "MD5" encrypted password using search engine like google, here you may find the original plain password. But if you mix the salt in your plain password and then apply "MD5" encryption, you wont be able to find it. If any hacker anyhow hacks your database and if you are using just MD5 encryption then he may use above method to hack passwords. For e.g. Search this string on google : 5f4dcc3b5aa765d61d8327deb882cf99, you'll get original password string. Salt is mainly added to protect against such attacks.
Check out here. Look at Just content and concept here to understand. This is from Spring security docs.
The purpose of a salt is not to prevent dictionary attacks; it is to prevent precomputation attacks such as rainbow tables. Having a salt requires the attacker to attack each password individually, after they gain access to the database; they can't precompute hashes for passwords in the dictionary, or reuse this effort across users.
Password Stretching is a way to make dictionary attacks more difficult, by increasing the amount of work the attacker has to do to test each candidate password.
Without salt, an attacker can use an offline attack to precalculate the hash of common passwords: "secret" "qwerty" etc. No salt allows an attacker to tell when different users are using the same password, as they will have the same hashes. Salt prevents precalculation and avoids the matching hash problem.
An attacker with access to the datbase will also have access to the salts. She will need to attack each password separately, because of the different salts.
Using stretching (repeated hashing) can also slow down an attacker. Rather than storing hash(password + salt) you store hash^n(password + salt), where n is large enough for the overall calculation to take at least 0.1 second . That limits the attacker to around ten trials a second while having no discernible impact on the user.

What are efficient ways to enhance the security of MD5 hashes?

I mean actually making it hard to exploit even if the user has chosen a relatively simple password(s)? I can't think of anything besides using additional cryptographic functions.
There are a few things you can do:
A cryptographically stronger hashing algorithm.
Salts
Key strengthening (e.g. bcrypt / scrypt / PBKDF2)
Use all these techniques for the best security.
The last is not particularly efficient in terms of performance, but that's deliberate. The problem with most commonly used cryptographic hash functions is that they are designed to be fast to compute, which means that they are also fast to crack if the password is a dictionary word. The idea of key strengthening is to make the algorithm so slow to compute that even a weak password will take a long time to crack.
Don't think, read ;) (and ask on SO) You'll want to salt passwords with their own individual salt so that the same password won't result in the same hash
http://en.wikipedia.org/wiki/Salt_(cryptography)
You might want to add a salt http://en.wikipedia.org/wiki/Salt_(cryptography) to the password you're going to hash. Anyway, be aware that there'll always be some risk associated with hashing a password, take a look at this article http://www.f-secure.com/weblog/archives/00002095.html
Leave crypto security, and analysis of it, to the experts, and just use a better crypto function.
Not using MD5 for hashing passwords. The same goes for about any hash function that's optimized for throughput. The idea of SHA1 and MD5 is, that you can generate a compact representation of virtually unlimited amounts of data, so that you can check it's integrity and also sign it cryptographically.
The idea of hashing passwords is, that you cannot retrieve the password from the hash. However most passwords are shorter than their hash, and implementing a brute force or dictionary attack is trivial. So given a hash, the used hash function one can implement the check logic locally -- possibly on a massive parallel computer, think GPU -- and break passwords reasonably fast.
What you actually want to do is using a hash function, that's so computationally intense that hashing takes so much time, that even attempting a brute force attack on a 4 character password took hours.
Just add some salt to the user entered password.
$salt = 'random string';
md5(sha1(md5($salt . $_POST['password'])));
Almost no way that result can be cracked.

Resources