2

I am trying to create a secure way for users to log in to and perform certain authorized actions on my custom website. I am trying to have good security without the use of SSL. At login now, this is what I am trying to improve:

  1. User types in credentials (e-mail and password)
  2. Client browser (JavaScript) one-way-hashes password with SHA-512, sends credential as login-request
  3. Java-based backend receives request, further encrypts the received password-hash(with salt etc) to fit the hashing in the database (which was created on registration), checks for match, and returns a cookie containing a fresh token.
  4. Backend also connects token to user in the database, and the backend will therefore know who future requests is coming from based on this token (without ever sending credentials in the request)

The idea is that if someone manages to pick up such a cookie (or the initial request), it's impossible to get the user's password.

This is great and all, but there's still the problem with repeat-attacks and man-in-the-middle-attacks, when 'bad guys' pick up a request, and uses the token to do stuff on another user's behalf.

By reading up on how to prevent this from happening, I have found that an acceptable method of preventing this could be adding a 'counter' to the token in the cookie, to show how many times the token has been used. Let's say the cookie initially contains a token and a counter of 0, like this cookie-content: "abc123:0", where the token is abc123, and the counter is 0. It's suggested that the client increment the counter every time a request is made. Let's say a user wants to send a chat-message to another user. The cookie attached to this request will then contain "abc123:1". The backend stores the counter as well as the token, and checks both values. If the received counter is more than the stored counter, awesome. If a 'bad guy' picks up the requests and try to repeat it, the counter will still be 1, and the server will reject it, as the stored counter also is 1(or more). This sounds great, but I'm not sure how this is any more secure? The 'bad guy' can simply edit the counter-value in the cookie to be 99999 and succeed?

I figured the content of the cookie (the token and the counter) should be hashed in some way, so that the content isn't plain-text. However, the client is HTML/JavaScript; the 'bad guy' can simply check which encryption-method is used, and decrypt it. All scripts are public.

I read something about improving this by sending a one-time 'secret' from the server to the client before the request is made, but I don't see how I can implement this. I guess, on requesting www.example.com/chat, I could generate a random 'secret', and send this to the client, and the client can add this to the cookie when sending a chat-message, or use it as a key, so that an encryption would be more secure, but how would the server know the secret upon receiving the request? How can the server reverse this? The server has to know the secret when decrypting it, so where should it be stored? Plain-text in the cookie next to the hash? Then the 'bad guy' can do the same thing. In the database? Upon requesting www.example.com/chat, should the backend know WHO is requesting it, so that it can be stored in the database along with that user? In that case, how should the backend authenticate the user, to be sure that there's not a man-in-the-middle or repeat-attack requesting /chat?

What is this method of security called, and is it possible to use it for what I need (with HTML/JavaScript)? If not, what are my options, beside SSL?

Sti
  • 8,275
  • 9
  • 62
  • 124
  • Take a look at [The definitive guide to form based website authentication](http://stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication). Most of the concepts described there are applicable to non-form based auth too. – Oleg Estekhin Jun 09 '14 at 05:47

1 Answers1

0

It's called bad security that does not rely on trust.

The client needs to fully trust the server, otherwise everything - including the page that is used to enter the password - cannot be trusted. Currently the only way of establishing trust is the certificate store that is provided within the browser (you should be able to trust the browser!). And the only software that is able to use it across browsers is SSL/TLS.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263