If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Enjoy an ad free experience by logging in. Not a member yet? Register.

The idea is, that each user will be identified and basically 'logged on' to the service via a 16-character key that only they have. This 'security mechanism' works by computing the md5 of the request and the key, e.g.

Code:

md5 = id123msgHelloa0dd9f...

(where it is a build of the request along with the key appended at the end. this is re-built on the server by re-generating the md5 and looking for a hash match)

I realize that this can be brute-forced, much like people are putting together rainbow tables and massive databases for passwords. However, the computational time to do something like this requires some serious processing power. But, the potential list of matches as a result of the brute force are relatively small, and can be tried one-by-one until a successful response is generated by the server.

The other thing is - since you already know everything that went into the md5 hash, including the md5 result, directly in the url, is it possible to create a tunneling program much like the way people are building md5 collision programs, to accomplish the same task of finding the 4-5 unknown blocks that went into the md5? I would expect if that is possible, it should generate a list of possible keys just like standard brute forcing, and also take considerably less processing time... but is that a possibility?

I was suggesting that this web service be protected by public/private key encryption - it needs to be something that is presently implemented in javascript, as calls need to be available strictly by javascript as well.

What are your suggestions? Is it reasonable to suggest that using md5 hashes in this manner to secure a web service is inherently insecure? And, is there a better mechanism as an alternative security option than public/private key encryption in this case?

Not sure how super secure this is, but basically when a user registers, I have a 3-character salt generated using chr(rand(35,126)). Not sure where those numbers came from but it has something to do with ASCII.
This is appended to an md5 hash of their password, and then encrypted AGAIN via md5. When they go to log-in, their password is encrypted, appended with the salt they have in the database, encrypted again, and checked against the their mumbo jumbo in the database. This way, you don't have the md5 hash just hanging out in your URL for everyone to see, but it's still accessible via the database.

You are correct in questioning the security of this setup. As far as I can see, you have the classic shared secret (key distribution) problem.

The id and message are sent out as plain text while the md5 hash is based on that plaintext plus other values known only to the client and server.

The biggest issue here is how the client recieves this secret (value or group of values). You mentioned that the client side is implemented in javascript.
How is the javascript delivered to the client?

Imagine the following scenario:

Attacker is capturing packets (tcpdump, ettercap, wireshark etc).

Client downloads javascript application.

Attacker grabs the shared secret over the wire.

Client sends a request to the server.

Attacker obtains the client's id.

The attacker can now create valid commands - md5(id+message+secret)

The system is compromised.

Script kiddies will probably be stumped by the existing system. A competent attacker will break it in no time flat.

Judging by the sample URL you posted, all this is going over http as GET requests. My first suggestion is to get SSL running*.
That will make sniffing packets more difficult (attacker will need a man-in-the-middle attack).

To provide any kind of security, the cypher text must be generated using a key known only to the client and server (and which is never revealed). This is the key distribution problem.
The best solution is, as you mentioned, public key crypto.**

MD5 has lost favour as a hash/digest recently too (see below). SHA is preferred although not perfect either.
PHP supports SHA256 via the hash() function:

PHP Code:

$cypherText = hash("sha256", $plainText);

As aalexaa suggested above, the proper use of a good salt will drastically reduce collisions (the basis for rainbow table attacks). The method aalexaa gave above is actually how vBulletin (forum engine this site runs on) deals with passwords:

Sorry. I was kind of all over the place there - insomnia driven crypto rant

Just reading over my post again, I gave no real recommendations. The way these things are usually done is via token generation. Both the server and client know a secret (password, dev key, etc). This is never transmitted in plain text.

When the client wants to send a message to the server, it creates a token based on that secret and a signature (digest/hash) of the message.

When the server receives the message, it regenerates the token (using the shared secret) and compares it to the received token. If the tokens match, the message is authenticated.

As I ranted about earlier, the security is provided by the shared secret. How this secret is delivered to the client will make or break the system. If you are sending it as plaintext over HTTP, the secret can be intercepted along the way and the system is insecure. If you were to send it over HTTPS, an attacker would have to use a man-in-the-middle attack to capture the secret. This is not easy to do, but the threat is there.

The system the OP described is, in a way, doing this but sending the secret in plain text. My recommendation is to look at the available options out there. Quite a lot of work has been done to develop authentication systems. In particular, I would suggest an implementation of OAuth: