views:

241

answers:

4

I have a website that requires a user to authenticate themselves with a user name and password. I would like to use SSL, but I don't have an SSL certificate. But I do something else that I think is okay.

My site is primarily AJAX based and requires JavaScript, otherwise nothing will work.

When the user tries to login, I query the database using AJAX to look for a salt for that user name, if none is found a random salt is returned (to keep people from knowing if there is a user with that user name or not). Then, using a MD5 function for JavaScript, I hash and salt the password 4K times (like Linux does when it uses MD5 for it's password hashing) client side, then I pass that hash to the server in plain text. This hash will then be hashed a few more times and presented to be checked with what's in the database.

Is this secure? If not, how can I secure it without forking over the cash for an SSL cert for a mostly internal website?

+15  A: 

No. It's not secure. A man-in-the-middle can snoop the hashed value and present it to you later, falsely authenticating himself.

To authenticate someone, you have to prove that they know a secret. Anything passed over an unencrypted channel is not a secret.

Use SSL. You can get certificates for free that are accepted by Firefox, and you can give IE users instructions for adding a new CA to their trusted roots. Certificates that are accepted by all browsers out of the box are cheap, I think $30 per year.

erickson
So what would the solution be, a nonce?
Malfist
You could dream up a solution using passwords and MACs on every request, but it would be full of holes that you wouldn't know about. And, it would be far more expensive to implement than buying a certificate.
erickson
+2  A: 

You could make your own SSL certificate for free, it wouldn't be trusted by general users but you can trust it.

By using JavaScript and a transport layer that is not encrypt, you open the possibility of someone grabbing that hash you send to your server, not to mention give an exact blueprint of how you are hashing the password/username.

It really depends on how important security is for that application. If it is very important drop the Ajax, and pick up a SSL certificate and use the HTTPS layer.

Martin Dale Lyness
If it's an internal site, self-signing may be the way to go - set up your own CA internally and issue yourself all the certificates you need. You just need to install the root certificate as trusted in all the client machines - any certificates issued thereafter will be trusted by those clients.If you need this to be an external site, go spend the extra money and get a real certificate.
Eclipse
+3  A: 

The best options are:

  • Use a certificate signed by StartCom (free). Supported natively by recent versions of Firefox and Safari. Users with IE can add the CA to their list of trusted roots.
  • Use a self-signed certificate and distribute it to your users to add in their browsers.

As others mention, your solution is not secure. It offers no improvement over sending the password in cleartext to the server. The major reasons:

  • Anything sent from the client in clear text and directly used to authenticate will be susceptible to man-in-the-middle and eavesdropping attacks. In your suggested solution, if you know the hashed password, you can log in. Sending the password as a hash makes no difference.
  • After authenticating, the data is still sent in plaintext, so it is easy to sniff.
  • MD5 is full of holes
molf
MD5 is full of holes? Can you explain how?
Malfist
@Malfist: added a link to my claim: the paper describes how a rogue CA was created using little more than MD5 exploits.
molf
+1  A: 

Your solution is open to replay attacks. Try Digest Authentication (RFC 2617) directly between the browser and web server.