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

SrpParameters thread-safety issue #3

Closed yallie closed 5 years ago

yallie commented 5 years ago

Looks like SrpParameters aren't thread safe because HashAlgorithm.ComputeHash isn't thread safe. The issue is easily reproduced like this:

[Test]
public async Task ParallelAuthenticationTest()
{
    var username = "demo";
    var password = "insecure";
    var parameters = new SrpParameters();
    var server = new SrpServer(parameters);

    // spawn multiple threads reusing the same SrpParameters instance
    var tasks = Enumerable.Range(0, 10).Select(i => Task.Run(() =>
    {
        var client = new SrpClient(parameters);

        // sign up
        var salt = client.GenerateSalt();
        var privateKey = client.DerivePrivateKey(salt, username, password);
        var verifier = client.DeriveVerifier(privateKey);

        // authenticate
        var clientEphemeral = client.GenerateEphemeral();
        var serverEphemeral = server.GenerateEphemeral(verifier);
        var clientSession = client.DeriveSession(clientEphemeral.Secret, serverEphemeral.Public, salt, username, privateKey);

        var serverSession = server.DeriveSession(serverEphemeral.Secret, clientEphemeral.Public, salt, username, verifier, clientSession.Proof);
        client.VerifySession(clientEphemeral.Public, clientSession, serverSession.Proof);

        // make sure both the client and the server have the same session key
        Assert.AreEqual(clientSession.Key, serverSession.Key);
    }));

    await Task.WhenAll(tasks);
}