secure-remote-password / srp.net

SRP-6a protocol implementation for .NET Standard 1.6+ and .NET Framework 3.5+
https://www.nuget.org/packages/srp
MIT License
64 stars 10 forks source link

How to verify the client again? #13

Closed jwillmer closed 2 years ago

jwillmer commented 2 years ago

Registration and authentication I understand but when the client calls an API and sends it's proof again do I have to drive a new session from it to check that he is authorized or is there some method to validate on the server that his proof matches mine?

On the client side I can validate the server proof like this: new SrpClient().VerifySession(Ephermal.Public, Session, proof);

How can I do the same on the server? And is it correct to send the proof on each request as you do with a jwt token?

yallie commented 2 years ago

Hi Jens,

session management is out of scope of this library because SRP only covers authentication.

To handle sessions you can use whatever method you like, such as encrypted JWT tokens. For example, the server can create a JWT token and send it to client on the last step. The client verifies server's response, and if it's ok, it then uses JWT token for subsequent calls. If server's response fails the verification, the client doesn't use the JWT token. Something like that I guess.

If you're designing a custom protocol with persistent connection, it's even better. At the end of SRP authentication sequence, both the client and the server have shared secret key. On the client it's clientSession.Key, on the server it's serverSession.Key.

This secret key is never sent across the wire, so it's pretty secure. By design of the protocol, a man-in-the-middle can neither see nor calculate this secret key. The key can be used to encrypt the traffic between connected parties using a symmetric algorithm. So, for persistent connection (like websockets), it looks like this:

  1. Connect to server and keep your duplex socket open
  2. Authenticate using SRP and calculate a unique secret key, shared on both ends
  3. Exchange encrypted messages (using Rijndael block cypher for example) no one can decode
  4. If the socket gets closed, reconnect, re-authenticate and get your fresh secret key.
jwillmer commented 2 years ago

O.K. I already figured and implemented JWT on top. Thanks for the clarification.