TL;DR Given that all of the state information for a web browser is accessible to a (potentially hostile) user, how can challenge-response authentication between the browser and the server be considered secure?
The Longer Version
I'm developing a web application and I want to implement web sockets for communication between the client and the server. I'm looking at implementing a WAMP router and I'm trying to understand modes of authentication with a system like this.
The WAMP protocol allows for challenge-response authentication (CRA). The way I understand it (and please correct me if I have this wrong), when a client makes a request to connect, the server sends a challenge. The client then encrypts the challenge using a secret key which is shared between the client and the server and returns it. The server checks the encrypted version from the client and, if it was correctly encrypted, allows access. The use of a shared secret allows the server to know that the request came from an authorized client.
In thinking about this question, I've come up with a solution that I think might solve the problem.
Important note: all connections will be secured via TLS.
Here's how my authentication system might work:
user logs in through the normal, form-based authentication method
server generates an authentication key and a secret, and passes those values to the client as part of the page HTML. The key and secret are both generated via a cryptographically secure method.
client then initiates websocket connection. This begins the challenge-response authentication sequence, using the key and secret generated by the server
server authenticates, using key & secret, and everything is cool.
The key here is the one-time use of the key and secret values. If they change periodically, then there is no way an attacker could generate a key/secret pair or use one that they had saved from a previous visit.
Which brings me to question #2: is this an adequate authentication scheme?
And finally, question #3: assuming the authentication scheme described above is adequate, how often should the key/secret values change? I'm thinking it should definitely change every time the user logs in, and should also expire after 6-8 hours have elapsed. Thoughts?