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

Intended lifetime of SrpClient and SrpServer classes #23

Closed PhotoAtomic closed 10 months ago

PhotoAtomic commented 10 months ago

Are SrpClient and SrpServer classes intended to be newly instantiated for each authentication roundtrip, or it is better to instantiate once at the start of the application (both client and server) and keep reuising the same instance?

Is there any security problem in reusing SrpServer for each authentication roundtrip from different clients?

I've verified that it is not possible to instantiate different SrpClient for each authentication phases (M1 and M2 must share the same SrpClient instance) but it works as intended if the same instance is shared for all the authentication roundtrip, so by extension, I'm wondering which is the most secure approach, if to keep the instance for future authentication as well (a singleton both on client and server) or to instantiate new one when it is needed (Basically with a "session" lifetime) or any working combination of this.

Expert help required! :)

yallie commented 10 months ago

Hi @PhotoAtomic,

I'm no security expert, but I can assure that SrpClient and SrpServer are essentially stateless. The only state they have is SrpParameters instance (prime number, multiplier, hash function, etc). So there should be no difference whether you use the same client/server instances or recreate them for every new user session.

I've verified that it is not possible to instantiate different SrpClient for each authentication phases (M1 and M2 must share the same SrpClient instance)

I'm surprised that you failed to use different client instances for auth phases. It should be possible to use new instances for every operation, i.e.:

// sign up
var salt = new SrpClient().GenerateSalt();
var privateKey = new SrpClient().DerivePrivateKey(salt, Username, Password);
var verifier = new SrpClient().DeriveVerifier(privateKey);

// authenticate
var clientEphemeral = new SrpClient().GenerateEphemeral();
var serverEphemeral = new SrpServer().GenerateEphemeral(verifier);
var clientSession = new SrpClient().DeriveSession(clientEphemeral.Secret, serverEphemeral.Public,
  salt, Username, privateKey);

// establish secure session
var serverSession = new SrpServer().DeriveSession(serverEphemeral.Secret, clientEphemeral.Public,
  salt, Username, verifier, clientSession.Proof);
new SrpClient().VerifySession(clientEphemeral.Public, clientSession, serverSession.Proof);

// make sure both the client and the server have the same session key
Console.WriteLine($"Authentication successful = {clientSession.Key == serverSession.Key}");

You can play with this sample at DotNetFiddle.

PhotoAtomic commented 10 months ago

I confirm you are correct, it was my fault, I'm also trying out a new testing framework and the problem was elsewere. Thanks for your help!

yallie commented 10 months ago

You're welcome!