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

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.

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.

Bcrypt for password hashing because it is slow?

I read today on not-implemented.com :
Sha-256 should be chosen in most cases where a high speed hash function is desired. It is considered secure with no known theoretical vulnerabilities and it has a reasonable digest size of 32 bytes. For things like hashing user password, though, a function designed to be slow is preferred: a great one is bcrypt.
Can somebody explain the last sentence :
For things like hashing user password, though, a function designed to be slow is preferred: a great one is bcrypt.
I don't say it's not correct, my question is simply:
Why it is preferred for hashing user password to use a slow function ?
Because if it takes more time to hash the value, it also takes a much longer time to brute-force the password.
Keep in mind that slow means that it requires more computing power. The same goes for when a potential hacker tries to brute-force a password.
On your side, the password hash needs to be computed rather rarely. But an attacker who tries to brute force a password from a stolen hash, relies on computing as many hashes as possible.
So, if your login now takes 100 ms instead of 0.1 (probably less) that's not really a problem for you. But it makes a huge difference for an attacker if he needs 2000 days to break a password instead of 2 days.
bcrypt is designed to be slow and not to allow any shortcut.
It takes more effort to brute force attack the password. The slower the algorithm, the less guesses can be made per second. The extra time won't be noticed by a user of the system, but will make it harder to crack the password.
Brute force a hash password?. It's easy to say than done.
If the passwords are not using a SALT then it is possible to break it, no matter the kind of encryption (because we could use a dictionary / pre-calculated hash attack).
The speed of the algorithm means nothing, it's just a myth that some people are spreading for the wrong reasons.
For example the next example:
Our hash is generated with the next formula:
MD5(SALT+MD5(SALT+VALUE))
Even if we could generate every possible combination of md5 in a split of a second, how we know if we found the right value?. And the answer is no, it's not possible. MD5 (or sha) doesn't check if the value is right or not, it simply generates a sequence of values and nothing more.
We could try a force brute attack if and only if we have a way to determine if our hash generated match some criteria. These criteria could be a dictionary and it means a slow process too and only if we could find some criteria.

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

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...)

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.

Do similar passwords have similar hashes?

Our computer system at work requires users to change their password every few weeks, and you cannot have the same password as you had previously. It remembers something like 20 of your last passwords. I discovered most people simply increment a digit at the end of their password, so "thisismypassword1" becomes "thisismypassword2" then 3, 4, 5 etc.
Since all of these passwords are stored somewhere, I wondered if there was any weakness in the hashes themselves, for standard hashing algorithms used to store passwords like MD5. Could a hacker increase their chances of brute-forcing the password if they have a list of hashes of similar passwords?
With a good hash algorithm, similar passwords will get distributed across the hashes. So similar passwords will have very different hashes.
You can try this with MD5 and different strings.
"hello world" - 5eb63bbbe01eeed093cb22bb8f5acdc3
"hello world" - fd27fbb9872ba413320c606fdfb98db1
Do similar passwords have similar hashes?
No.
Any similarity, even a complex correlation, would be considered a weakness in the hash. Once discovered by the crypto community it would be published, and enough discovered weaknesses in the hash eventually add up to advice not to use that hash any more.
Of course there's no way to know whether a hash has undiscovered weaknesses, or weaknesses known to an attacker but not published, in which case most likely the attacker is a well-funded government organization. The NSA certainly is in possession of non-public theoretical attacks on some crypto components, but whether those attacks are usable is another matter. GCHQ probably is. I'd guess that a few other countries have secret crypto programs with enough mathematicians to have done original work: China would be my first guess. All you can do is act on the best available information. And if the best available information says that a hash is "good for crypto", then one of the things that means is no usable similarities of this kind.
Finally, some systems use weak hashes for passwords -- either due to ignorance by the implementer or legacy. All bets are off for the properties of a hashing scheme that either hasn't had public review, or else has been reviewed and found wanting, or else is old enough that significant weaknesses have eventually been found. MD5 is broken for some purposes (since there exist practical means to generate collisions) but not for all purposes. AFAIK it's OK for this, in the sense that there is no practical pre-image attack, and having a handful of hashes of related plaintexts is no better than having a handful of hashes of unrelated plaintexts. But for unrelated reasons you shouldn't really use a single application of any hash for password storage anyway, you should use multiple rounds.
Could a hacker increase their chances of brute-forcing the password if they have a list of hashes of similar passwords?
Indirectly, yes, knowing that those are your old passwords. Not because of any property of the hash, but suppose the attacker manages to (very slowly) brute-force one or more of your old passwords using those old hashes, and sees that in the past it has been "thisismypassword3" and "thisismypassword4".
Your password has since changed, to "thisismypassword5". Well done, by changing it before the attacker cracked it, you have successfully ensured that the attacker did not recover a valuable password! Victory! Except it does you no good, since the attacker has the means to guess the new one quickly anyway using the old password(s).
Even if the attacker only has one old password, and therefore cannot easily spot a trend, password crackers work by trying passwords which are similar to dictionary words and other values. To over-simplify a bit, it will try the dictionary words first, then strings consisting of a word with one extra character added, removed or changed, then strings with two changes, and so on.
By including your old password in the "other values", the attacker can ensure that strings very similar to it are checked early in the cracking process. So if your new password is similar to old ones, then having the old hashes does have some value to the attacker - reversing any one of them gives him a good seed to crack your current password.
So, incrementing your password regularly doesn't add much. Changing your password to something that's guessable from the old password puts your attacker in the same position as they'd be in if they knew nothing at all, but your password was guessable from nothing at all.
The main practical attacks on password systems these days are eavesdropping (via keyloggers and other malware) and phishing. Trying to reverse password hashes isn't a good percentage attack, although if an attacker has somehow got hold of an /etc/passwd file or equivalent, they will break some weak passwords that way on the average system.
It depends on the hashing algorithm. If it is any good, similar passwords should not have similar hashes.
The whole point of a cryptographic hash is that similar passwords would absolutely not create similar hashes.
More importantly, you would most likely salt the password so that even the same passwords do not produce the same hash.
It depends on the hash algorithm used. A good one will distribute similiar inputs to disparate outputs.
Different Inputs may result in the same Hash this is what is called a hash collision.
Check here:
http://en.wikipedia.org/wiki/Collision_%28computer_science%29
Hash colisions may be used to increase chances of a successfull brute force attack, see:
http://en.wikipedia.org/wiki/Birthday_attack
To expand on what others have said, a quick test shows that you get vastly different hashes with small changes made to the input.
I used the following code to run a quick test:
<?php
for($i=0;$i<5;$i++)
echo 'password' . $i . ' - ' .md5('password' . $i) . "<br />\n";
?>
and I got the following results:
password0 - 305e4f55ce823e111a46a9d500bcb86c
password1 - 7c6a180b36896a0a8c02787eeafb0e4c
password2 - 6cb75f652a9b52798eb6cf2201057c73
password3 - 819b0643d6b89dc9b579fdfc9094f28e
password4 - 34cc93ece0ba9e3f6f235d4af979b16c
Short answer, no!
The output of a hash function varies greatly even if one character is increased.
But this is only if you want to break the hashfunction itself.
Of course, it is bad practice since it makes bruteforcing easier.
No, if you check the password even slightly it produces completely new hash.
As a general rule, a "good hash" will not hash two similar (but unequal) strings to similar hashes. MD5 is good enough that this isn't a problem. However, there are "rainbow tables" (essentially password:hash pairs) for quite a few common passwords (and for some password hashes, the traditional DES-based unix passwords, for example) full rainbow tables exist.

Resources