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.
Related
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.
Ok, so I understand why salting a password prior to hashing is such a good idea.
The question is, normally people suggest appending or prepending the salt to the password, why not do both?
My thinking is, so if Mr hacker got hold of the DB and wants to get the password for person x,
he thinks to himself, well most people suggest appending or prepending the salt, so lets do that..
He generates a rainbow table with of all the combinations of password + salt, and tries his luck. If that doesn't work he does the same but salt + password.
To make much it more difficult to do the attack why don't developers go the step further and do 'salt + password + salt', or 'reverse(salt) + password + salt', or you could be fancy and start cutting up the password/salt, start putting bits of salt here and there etc.
The only way the hacker would be able to find the password is if he has access to the source code (to know how the salt was weaved into the password prior to hashing)
A further note is, people suggest doing a minimum of 1000 iterations when key-stretching, again why not 1147, 1652, etc :)
A 2nd further note, when looking at a hash string, is it possible to work out the hashing function used?
It's much easier to guess the manner in which the salt is applied than it is to brute for the passwords, especially in the cases in which the attacker has a database of hashed passwords and one known match (his own password). Even if he has no knowledge of it, he can simply use his known password and the known hash to brute force the salt and salting algorithm.
The same goes with the hashing algorithm. There are only a few unbroken hash functions, and the chances are that any competent administrator would be using one of those.
One of the premises of cryptography is that ALL of the information about the algorithms used is assumed to be public. You should not rely on attackers to be unable to break your system because you are using an obscure algorithm to hash things, because compared to the expense of brute forcing passwords on a compromised database like that, brute forcing every hash algorithm is very inexpensive.
If you distribute your program to users, they can figure out exactly how it hashes things by disassembling or debugging it. If it's a server program, they can break in with some other vulnerability, or they can buy/steal/acquire your software, or whatever. I would even go so far as to say that ALL GOOD CRYPTOGRAPHIC SOFTWARE IS OPEN SOURCE: even though the entire world knows how it works, its still not breakable.
What you are trying to rely upon is security by obscurity. Lots of people and companies have used this as a method of securing their products. The last big incident I can remember was when the source code of Symantec's PCAnywhere software was stolen. You might remember how that turned out. Moral of the story is it isn't secure if nobody knows how it works, its secure if EVERYONE knows how it works (and it's cryptographically sound).
Reverse engineering your code would not be too hard for a determained hacker, once that happens, every one of your passwords is now compromised.
You should use proven hashing techniques. Take, for example, something similar to the bcrypt algorithm. When you want to hash a password, go through the following steps:
Generate a sufficiently strong random salt (16 - 32 bytes)
Set a hash cost (15 - 20) (the larger the cost, the slower and stronger the hash)
Calculate the number of hash rounds you will perform (2^cost)
Do the following:
hash = ""
for(numberOfHashRounds)
{
hash = SHA256(hash + salt + password)
}
Then store the hash along with the salt and cost used. When you need to verify, do the same with the stored salt and cost. As computers get faster, you can up the cost of the algorithm. Try and get it so your hash takes ~500ms to compute, or as long as you are willing to sacrafice.
This is secure because a cracker would have to generate a rainbow table for every salt, and perform the same number of rounds. This will take decades even with a GPU array used to crack.
If you want to add obfuscation on top of that, go ahead, just dont break the security of your algorithm in the process.
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.
I just spent some time reading https://stackoverflow.com/questions/2768248/is-md5-really-that-bad (I highly recommend!).
In it, it talks about hash collisions. Maybe I'm missing something here, but can't you just encrypt your password using, say, MD5 and then, say, SHA-1 (or any other, doesn't matter.) Wouldn't this increase the processing power required to brute-force the hash and reduce the possibility of collision?
First of all md5 and sha1 are not encryption functions, they are message digest functions. Also most hashes are broken in real world using dictionary attacks like John The Ripper and Rainbow Crack.
John The Ripper is best suited for salted passwords where the attacker knows the salt value. Rainbow Crack is good for passwords with small unknown salts and straight hashes like md5($pass).
Rainbow Crack takes a long time to build the tables, but after that passwords break in a matter of seconds. It depends on how fast your disk drives are.
You are talking about 2 distinct (although related) problems. First is the likely-hood of a collision, and the second is the ability to run the algorithm on tons of values to find the original value which created the hash.
Collisions. If you run sha1(md5(text)) you first get the hash of md5, then pass that to sha1. Lets assume the sha1 function has a 128-bit output, and the md5 also has 128-bit output. Your chance of collision in the md5 function is 1/2^128. Then your chance of collision in the sha1 is 1/2^128. If either collides then the function overall collides and hence the result is (1/2^128) + (1/2^128) or 1/2^127
Brute forcing. Running sha1(md5(text)) will only double the time it takes to find the original string. This is nothing in terms of security. FOr instance, if you have 128-bits of output space for each algorithm, and it takes 1 hour to brute force, then it will take 2 hours to run the same brute force twice to get the original string. This would be the same as increasing the output space to 129-bits. However, if you want to really make brute forcing impossible, what you have to do is double the output-size (which can be compared to the key size in encryption).
A collision attack (the type that's known against MD5, for example) does no real good. To be effective with regard to a password, you need a preimage attack (i.e. the ability to find some input that will hash to a known hash code). Though there are preimage attacks known against MD5, they're not currently practical.
Collision attacks are useful for entirely different purposes. One example that's been carried out is creating two X.509 certificates for two different identities that collide. Submit one to be signed by a certificate authority, and then you can use the other to claim that you're somebody else entirely. Since the hash will collide with the first, when/if a user tries to verify the certificate, it will show up as having been verified.
First not encryption creating Message Digest using the hash functions.
your question:
but can't you just encrypt (hash) your
password using, say, MD5 and then,
say, SHA-1 (or any other, doesn't
matter.)
if the hash function does not provide any of these properties, it does not matter how many times you hashed, also the attacker can hash n times to get the collisions.
For any given code h, it is computationally infeasible to find
such x that H(x)=h, this property is
called one way or preimage resistant.
For any given block x ,it is computationally infeasible to find y≠x
with H(y)=H(x).This property is
referred second preimage resistant or
weak collision resistant
It is computationally infeasible to find any pear (x,y) such that
H(x)=H(y). This is called Strong
collision resistant.
So as The Rook mentioned, the passwords are stored by adding different salt values for each users. The dictionary gets longer and also computational overhead and time gets longer for the attacker if she exploits the password file.
Let's say attacker has the hashed values of the passwords, and starts reading from the dictionary file and compares with the hashed values if matches then pasword is cracked, if salt is used then read from the dictionary and add some salt value then try to find a match.However this should be done for each user. So the complexity that salt adds is (from wikipedia)
Assume a user’s (encrypted) secret key
is stolen and he is known to use one
of 200,000 English words as his
password. The system uses a 32-bit
salt. The salted key is now the
original password appended to this
random 32-bit salt. Because of this
salt, the attacker’s pre-calculated
hashes are of no value. He must
calculate the hash of each word with
each of 2^32 (4,294,967,296) possible
salts appended until a match is found.
The total number of possible inputs
can be obtained by multiplying the
number of words in the dictionary with
the number of possible salts:
if H(password+salt)(in system)=H(Your password+salt) (login process)
login else
print<<error
When you hash a password multiple times you actually increase the chance of hash collisions, so best practice is to hash only once.
It also has nothing to do with how easy it will be to perform a brute-force attack. Such an attack will systematically try every possible password within a given range. Thus, if your password is "foobar" and the attack tests the password "foobar" it wont matter how or how many times you hashed the password, because the brute-force attack successfully guessed it.
Therefore, if you wish to guard yourself against a brute-force attack, you could limit how often a user can attempt authorization or require passwords to be above a certain length.
On a side note; Rainbow Tables and similar methods are used by hackers that have already gained access to your database and are meant to decrypt the stored password. In order make such an attack more difficult, you should use static and dynamic salts.
Hashing a hash is sort of "encryption though obfuscation" which isn't really a best practice. You're right in that it could theoretically "reduce" the possibility of a collision but it probably wont eliminate the possibility. Whats more, a hashing function isn't really an encrypting function, google "hashing vs encrypting" for several hundred explanations.
What is the slowest (therefore best) hash algorithm for passwords in ASP Classic?
EDIT: For those unaware, when hashing passwords, slower hashes are preferred to faster to help slow rainbow table style attacks.
EDIT2: And yes, of course speed isn't the only valid concern for hash selection. My question assumes that All other things being equal, the slowest hash method is preferred when hashing a password. Though collision/reverse engineering is of course a concern too, I'm prioritizing speed in this question since it is arguably the most critical factor to consider when comparing popular hash algorithms for use on passwords.
Thanks!
A lot of people seem to be beating on the question-asker because he's looking for a slow hash function. Actually, all other aspects being equal, a slower hash function is more secure than a fast one. This is because a slower hash function results in slower generation of rainbow tables and slower brute forcing or dictionary attacks on the password.
From Thomas Ptacek at http://www.securityfocus.com/blogs/262, as referenced in this Coding Horror article:
The problem is that MD5 is fast. So
are its modern competitors, like SHA1
and SHA256. Speed is a design goal of
a modern secure hash, because hashes
are a building block of almost every
cryptosystem, and usually get
demand-executed on a per-packet or
per-message basis.
Speed is exactly what you don’t want
in a password hash function.
Modern password schemes are attacked
with incremental password crackers.
Incremental crackers don’t
precalculate all possible cracked
passwords. They consider each password
hash individually, and they feed their
dictionary through the password hash
function the same way your PHP login
page would. Rainbow table crackers
like Ophcrack use space to attack
passwords; incremental crackers like
John the Ripper, Crack, and LC5 work
with time: statistics and compute.
The password attack game is scored in
time taken to crack password X. With
rainbow tables, that time depends on
how big your table needs to be and how
fast you can search it. With
incremental crackers, the time depends
on how fast you can make the password
hash function run.
The better you can optimize your
password hash function, the faster
your password hash function gets, the
weaker your scheme is. MD5 and SHA1,
even conventional block ciphers like
DES, are designed to be fast. MD5,
SHA1, and DES are weak password
hashes. On modern CPUs, raw crypto
building blocks like DES and MD5 can
be bitsliced, vectorized, and
parallelized to make password searches
lightning fast. Game-over FPGA
implementations cost only hundreds of
dollars.
Some comments on the PHP MD5 documentation also discuss preference for slowness.
To answer your question, it looks like BCrypt is the way to go. However, I have not been able to find any implementations for ASP Classic. If that's true, I would stick with a regular hash function like SHA512.
I'll ignore the slow part, and instead go for the "good" part.
I suggest you use SHA-512 with a salt to defeat dictionary and rainbow table attacks. I don't believe there are any known vulnerabilities for SHA-512.
If you are trying to defeat brute force attacks you are better off enforcing some failed attempts window/count rather than relying on the speed of the hashing (or hash comparison) mechanism to make the attack take longer to succeed. Lock out the account after a certain number of failed attempts within the failure window and only let new attempts be made after a significant amount of time has elapsed.
This could leave you open to a DOS attack against a well-known (administrative) account, but you could exempt certain accounts from the lockout policy or have an alternate way -- using a security question/answer -- to logon to a locked out account before the reset period has elapsed.
[EDIT] To help defeat rainbow attacks -- where the attacker has retrieved your hashed passwords and finds suitable matches that hash to the same values -- consider both using a random salt unique to each user's hashed password and a fixed salt that is part of the algorithm, not the data. For example:
testHash = computeHash( user.salt + "98hloj5674" + password );
if (testHash == user.hashedPassword)
{
valid = true;
}
This should invalidate the rainbow tables since, even knowing the user's salt and the hash algorithm, the values in the attacker's rainbow tables won't map onto your hashed passwords because of the addition of the fixed salt in the algorithm.
With ASP Classic, you'd have to do this in a library instead of on the page to make sure that the user couldn't see your fixed salt.
Dim sPassword, sSalt
sPassword = "Lorem"
sSalt = "Ipsum"
With CreateObject("CAPICOM.HashedData")
.Algorithm = 0 ' CAPICOM_HASH_ALGORITHM_SHA1
.Hash sPassword & sSalt
Response.Write "Here is your hash: " & .Value
End With
Capicom documentation
Algorithm is any of the following:
CAPICOM_HASH_ALGORITHM_SHA1 = 0
CAPICOM_HASH_ALGORITHM_MD2 = 1
CAPICOM_HASH_ALGORITHM_MD4 = 2
CAPICOM_HASH_ALGORITHM_MD5 = 3
CAPICOM_HASH_ALGORITHM_SHA_256 = 4 - Not supported on Windows XP or 2000
CAPICOM_HASH_ALGORITHM_SHA_384 = 5 - Not supported on Windows XP or 2000
CAPICOM_HASH_ALGORITHM_SHA_512 = 6 - Not supported on Windows XP or 2000
Actually, the best hash function is the one that generates no colisions and is not suspectible to rainbow-table attacks.
That means: Add a Salt (preferably a different Salt for every user), and think of using a SHA2 Hash function (or maybe RIPE-MD, I have not looked at that much):
One implementation of SHA-256 is here (i love how they call it "one-way encryption"):
http://www.freevbcode.com/ShowCode.Asp?ID=2565
Have not tested it though, but there are certainly SHA2 implementations for Classic ASP.
I personally prefer the Whirlpool algorithm for all of my hashing needs. It produces a 512 bit output and thus has equal space requirements to SHA-512. Regretfully, I cannot speak authoritatively as to whether one is more secure than the other, but there do not appear to be any flagrant weaknesses in this the third version of Whirlpool.
The reference implementations are in the public domain, which is good because I rarely find this implemented by default in various tools and languages.
(If anyone knows of a good reason why SHA should be favored over Whirlpool, please let me know.)
psuedocode for the slowest method:
function hashPassword(password)
sleep for 10 seconds
return password
end function
This certainly isn't the most secure (or at all) but it's slow...
(I'm just pointing out that making it slower is not the answer...)