views:

948

answers:

11

I've seen a few questions and answers on SO suggesting that MD5 is less secure than something like SHA.

My question is, Is this worth worrying about in my situation?

Here's an example of how I'm using it:

  1. On the client side, I'm providing a "secure" checksum for a message by appending the current time and a password and then hashing it using MD5. So: MD5(message+time+password).
  2. On the server side, I'm checking this hash against the message that's sent using my knowledge of the time it was sent and the client's password.

In this example, am I really better off using SHA instead of MD5?

In what circumstances would the choice of hashing function really matter in a practical sense?

Edit:

Just to clarify - in my example, is there any benefit moving to an SHA algorithm?

In other words, is it feasible in this example for someone to send a message and a correct hash without knowing the shared password?

More Edits:

Apologies for repeated editing - I wasn't being clear with what I was asking.

+5  A: 

It depends on how valuable the contents of the messages are. The SHA family is demonstrably more secure than MD5 (where "more secure" means "harder to fake"), but if your messages are twitter updates, then you probably don't care.

If those messages are the IPC layer of a distributed system that handles financial transactions, then maybe you care more.

Update: I should add, also, that the two digest algorithms are essentially interchangeable in many ways, so how much more trouble would it really be to use the more secure one?

Update 2: this is a much more thorough answer: http://www.schneier.com/essay-074.html

Ben Collins
As far as I can tell (not that it matters in my case), SHA is more resource-intensive than MD5 being that it's a more complicated algorithm.
Damovisa
The important part of this message is the point that the answer really depends on the context. If you're doing PKI (certificates) then an attack has been proven that breaks this use. If you're doing cache validation, then security is not really as big a concern (and in fact the increased spped, as Damovisa points out, may be beneficial).
gregmac
The main thing is that you have to define more precisely what "better off" means for your application.
Ben Collins
Thanks - I've updated the question to more accurately describe my purpose
Damovisa
A: 

There is nothing insecure about using MD5 in this manner. MD5 was only broken in the sense that, there are algorithms that, given a bunch of data A additional data B can be generated to create a desired hash. Meaning, if someone knows the hash of a password, they could produce a string that will result with that hash. Though, these generated strings are usually very long so if you limit passwords to 20 or 30 characters you're still probably safe.

The main reason to use SHA1 over MD5 is that MD5 functions are being phased out. For example the Silverlight .Net library does not include the MD5 cryptography provider.

Spencer Ruport
+17  A: 

Yes, it is worth worrying about in practice. MD5 is so badly broken that researchers have been able to forge fake certificates that matched a real certificate signed by a certificate authority. This meant that they were able to create their own fake certificate authority, and thus could impersonate any bank or business they felt like with browsers completely trusting them.

Now, this took them a lot of time and effort using a cluster of PlayStation 3s, and several weeks to find an appropriate collision. But once broken, a hash algorithm only gets worse, never better. If you care at all about security, it would be better to choose an unbroken hash algorithm, such as one of the SHA-2 family (SHA-1 has also been weakened, though not broken as badly as MD5 is).

edit: The technique used in the link that I provided you involved being able to choose two arbitrary message prefixes and a common suffix, from which it could generate for each prefix a block of data that could be inserted between that prefix and the common suffix, to produce a message with the same MD5 sum as the message constructed from the other prefix. I cannot think of a way in which this particular vulnerability could be exploited in the situation you describe, and in general, using a secure has for message authentication is more resistant to attack than using it for digital signatures, but I can think of a few vulnerabilities you need to watch out for, which are mostly independent of the hash you choose.

  1. As described, your algorithm involves storing the password in plain text on the server. This means that you are vulnerable to any information disclosure attacks that may be able to discover passwords on the server. You may think that if an attacker can access your database then the game is up, but your users would probably prefer if even if your server is compromised, that their passwords not be. Because of the proliferation of passwords online, many users use the same or similar passwords across services. Furthermore, information disclosure attacks may be possible even in cases when code execution or privilege escalation attacks are not.

    You can mitigate this attack by storing the password on your server hashed with a random salt; you store the pair <salt,hash(password+salt)> on the server, and send the salt to the client so that it can compute hash(password+salt) to use in place of the password in the protocol you mention. This does not protect you from the next attack, however.

  2. If an attacker can sniff a message sent from the client, he can do an offline dictionary attack against the client's password. Most users have passwords with fairly low entropy, and a good dictionary of a few hundred thousand existing passwords plus some time randomly permuting them could make finding a password given the information an attacker has from sniffing a message pretty easy.

  3. The technique you propose does not authenticate the server. I don't know if this is a web app that you are talking about, but if it is, then someone who can perform a DNS hijack attack, or DHCP hijacking on an unsecure wireless network, or anything of the sort, can just do a man-in-the-middle attack in which they collect passwords in clear text from your clients.

  4. While the current attack against MD5 may not work against the protocol you describe, MD5 has been severely compromised, and a hash will only ever get weaker, never stronger. Do you want to bet that you will find out about new attacks that could be used against you and will have time to upgrade hash algorithms before your attackers have a chance to exploit it? It would probably be easier to start with something that is currently stronger than MD5, to reduce your chances of having to deal with MD5 being broken further.

Now, if you're just doing this to make sure no one forges a message from another user on a forum or something, then sure, it's unlikely that anyone will put the time and effort in to break the protocol that you described. If someone really wanted to impersonate someone else, they could probably just create a new user name that has a 0 in place of a O or something even more similar using Unicode, and not even bother with trying to forge message and break hash algorithms.

If this is being used for something where the security really matters, then don't invent your own authentication system. Just use TLS/SSL. One of the fundamental rules of cryptography is not to invent your own. And then even for the case of the forum where it probably doesn't matter all that much, won't it be easier to just use something that's proven off the shelf than rolling your own?

Brian Campbell
That's fair, but in this instance, is it relevant? I'm just not sure in what way it's broken - is it broken in a way that makes my situation vulnerable to attack?
Damovisa
That's a great update, thanks :)
Damovisa
One of the major problems I have with my particular situation is that MD5 is the only hash algorithm provided from the client side (yes, it's an old system).
Damovisa
@Brian, 1) does not really mitigate the fundamental issue that the wrong algorithm is being used (you can still intercept the salt and the salt will probably be stored on the client. 2) is the fundamental issue, I agree with you on it. 4) the thing about MD5 being severely compromised, is imho out of proportion, MD5 is susceptible to collision attacks, that fact does not make it more or less likely to be susceptible to preimage attacks.
Sam Saffron
@sambo99 The salt is a standard technique used to prevent pre-computed dictionary attacks and rainbow table attacks. It does not prevent a straight up dictionary attack, but a straight up dictionary attack is much more expensive than a rainbow table attack. That's why I said "mitigate" rather than "solve". Perhaps I should have been more clear. On point 4, fair enough. That was basically just added as a throwaway extra point, to add onto all the rest, so that my suggestion of using an existing cryptographic protocol would be stronger.
Brian Campbell
A: 

MD5 provide more collision than SHA which mean someone can actually get same hash from different word (but it's rarely).

SHA family has been known for it's reliability, SHA1 has been standard on daily use, while SHA256/SHA512 was a standard for government and bank appliances.

For your personal website or forum, i suggest you to consider SHA1, and if you create a more serious like commerce, i suggest you to use SHA256/SHA512 (SHA2 family)

You can check wikipedia article about MD5 & SHA

Dels
+2  A: 

Yes, someone can send a message and a correct hash without knowing the shared password. They just need to find a string that hashes to the same value.

How common is that? In 2007, a group from the Netherlands announced that they had predicted the winner of the 2008 U.S. Presidential election in a file with the MD5 hash value 3D515DEAD7AA16560ABA3E9DF05CBC80. They then created twelve files, all identical except for the candidate's name and an arbitrary number of spaces following, that hashed to that value. The MD5 hash value is worthless as a checksum, because too many different files give the same result.

This is the same scenario as yours, if I'm reading you right. Just replace "candidate's name" with "secret password". If you really want to be secure, you should probably use a different hash function.

Bruce Alderman
Fair enough - the difference I think is that in a faked hash, the other pieces of data required for the hash function will make no sense. While someone may very well be able to find a value Y where MD5(Y) = MD5(message+time+password), Y will make no sense in the context.
Damovisa
To summarize the previous comment, finding a Y where MD5(Y) = MD5(message+time+password) is definitely possible, yes. However finding a Y such that MD5(X+time+Y) is probably more difficult - especially because "time" is constantly changing...
Damovisa
+9  A: 

In this particular case, I don't think that the weakest link your application is using md5 rather than sha. The manner in which md5 is "broken" is that given that md5(K) = V, it is possible to generate K' such that md5(K') = V, because the output-space is limited (not because there are any tricks to reduce the search space). However, K' is not necessarily K. This means that if you know md5(M+T+P) = V, you can generate P' such that md5(M+T+P') = V, this giving a valid entry. However, in this case the message still remains the same, and P hasn't been compromised. If the attacker tries to forge message M', with a T' timestamp, then it is highly unlikely that md5(M'+T'+P') = md5(M'+T'+P) unless P' = P. In which case, they would have brute-forced the password. If they have brute-forced the password, then that means that it doesn't matter if you used sha or md5, since checking if md5(M+T+P) = V is equivalent to checking if sha(M+T+P) = V. (except that sha might take constant time longer to calculate, that doesn't affect the complexity of the brute-force on P).

However, given the choice, you really ought to just go ahead and use sha. There is no sense in not using it, unless there is a serious drawback to using it.

A second thing is you probably shouldn't store the user's password in your database in plain-text. What you should store is a hash of the password, and then use that. In your example, the hash would be of: md5(message + time + md5(password)), and you could safely store md5(password) in your database. However, an attacker stealing your database (through something like SQL injection) would still be able to forge messages. I don't see any way around this.

FryGuy
That's an awesome answer, thanks.
Damovisa
Ach. You managed to post this while I was writing my edit to respond to the question clarification. Oh, well, I hope my edit is still helpful.
Brian Campbell
@Brian - it was very helpful, thanks
Damovisa
A: 

if you are going to generate a hash-mac don't invent your scheme. use HMAC. there are issues with doing HASH(secret-key || message) and HASH(message || secret-key). if you are using a password as a key you should also be using a key derivation function. have a look at pbkdf2.

drscroogemcduck
+3  A: 

Brian's answer covers the issues, but I do think it needs to be explained a little less verbosely

You are using the wrong crypto algorithm here

MD5 is wrong here, Sha1 is wrong to use here Sha2xx is wrong to use and Skein is wrong to use.

What you should be using is something like RSA.

Let me explain:

Your secure hash is effectively sending the password out for the world to see.

You mention that your hash is "time + payload + password", if a third party gets a copy of your payload and knows the time. It can find the password (using a brute force or dictionary attack). So, its almost as if you are sending the password in clear text.

Instead of this you should look at a public key cryptography have your server send out public keys to your agents and have the agents encrypt the data with the public key.

No man in the middle will be able to tell whats in the messages, and no one will be able to forge the messages.

On a side note, MD5 is plenty strong most of the time.

Sam Saffron
Actually, I did mention the same vulnerability that you mention here, and I also suggested using SSL/TLS for his purposes if possible. I also tried to answer his specific question, since I felt that was polite, even though I felt like he was on the wrong track.
Brian Campbell
@Brian Your answer is a much better candidate for the correct answer to this question
Sam Saffron
Yeah, I finished my edit after the accepted answer had been selected. +1 for helping point out some of the core issues here; I was a little too verbose and let them be lost among some weaker points.
Brian Campbell
I'm just catching up on this answer and I've noted the newer responses... not sure what to do here - it's clear that I accepted an answer too early...
Damovisa
Well 2 things you should do .... accept Brian's answer and ... if you care to protect the passwords against a brute force or dictionary attack look at moving to public/private key based algorithm
Sam Saffron
A: 

Both MD5 amd SHA-1 have cryptographic weaknesses. MD4 and SHA-0 are also compromised.

You can probably safely use MD6, Whirlpool, and RIPEMD-160.

See the following powerpoint from Princeton University, scroll down to the last page.

http://gcu.googlecode.com/files/11Hashing.pdf

Unknown
A: 

I'm not going to comment on the MD5/SHA1/etc. issue, so perhaps you'll consider this answer moot, but something that amuses me very slightly is whenever the use of MD5 et al. for hashing passwords in databases comes up.

If someone's poking around in your database, then they might very well want to look at your password hashes, but it's just as likely they're going to want to steal personal information or any other data you may have lying around in other tables. Frankly, in that situation, you've got bigger fish to fry.

I'm not saying ignore the issue, and like I said, this doesn't really have much bearing on whether or not you should use MD5, SHA1 or whatever to hash your passwords, but I do get tickled slightly pink every time I read someone getting a bit too upset about plain text passwords in a database.

Rob
+1  A: 

Yes, it is worth to worry about which hash to use in this case. Let's look at the attack model first. An attacker might not only try to generate values md5(M+T+P), but might also try to find the password P. In particular, if the attacker can collect tupels of values Mi, Ti, and the corresponding md5(Mi, Ti, P) then he/she might try to find P. This problem hasn't been studied as extensively for hash functions as finding collisions. My approach to this problem would be to try the same types of attacks that are used against block ciphers: e.g. differential attacks. And since MD5 already highly susceptible to differential attacks, I can certainly imagine that such an attack could be successful here.

Hence I do recommend that you use a stronger hash function than MD5 here. I also recommend that you use HMAC instead of just md5(M+T+P), because HMAC has been designed for the situation that you describe and has accordingly been analyzed.

Accipitridae