Skip to content

Using SRP 6a protocol

Alexey Yakovlev edited this page May 21, 2018 · 7 revisions

Quoting the Wikipedia article:

The Secure Remote Password protocol (SRP) is an augmented password-authenticated key agreement (PAKE) protocol, specifically designed to work around existing patents.

Like all PAKE protocols, an eavesdropper or man in the middle cannot obtain enough information to be able to brute force guess a password without further interactions with the parties for each guess. This means that strong security can be obtained using weak passwords. Furthermore, being an augmented PAKE protocol, the server does not store password-equivalent data. This means that an attacker who steals the server data cannot masquerade as the client unless they first perform a brute force search for the password.

In layman's terms, during SRP (or any other PAKE protocol) authentication, one party (the "client" or "user") demonstrates to another party (the "server") that they know the password, without sending the password itself, nor any other information from which the password can be broken. The password never leaves the client and is unknown to the server.

Zyan implementation notes

Zyan SRP-6a implementation is based on (and is compatible with) secure-remote-password npm module by Linus Unnebäck. This means you can use credentials generated by the npm module to authenticate your Zyan application (and vice versa).

To enable SRP-6a authentication, use the following classes:

  • SrpAuthCredentials — on the client side
  • SrpAuthenticationProvider — on the server side

Client-side code

var url = "tcpex://localhost:8090/MyServer";
var protocol = new TcpDuplexClientProtocolSetup(true);
var credentials = new SrpAuthCredentials("[email protected]", "secret");

using (var connection = new ZyanConnection(url, protocol, credentials, true, true))
{
	var proxy = connection.CreateProxy<ISampleServer>();
	...
}

Note that while you still provide user name and password to the SrpAuthCredentials constructor, the password is never sent across the wire (neither plain-text, nor encrypted). Only user name is sent to the server.

Server-side code

var userAccountRepository = new UserAccountRepository(); // implement this class
var authProvider = new SrpAuthenticationProvider(accounts);
var protocol = new TcpDuplexServerProtocolSetup(8090, provider, true);
var host = new ZyanComponentHost("MyServer", protocol);
host.RegisterComponent<ISampleServer, SampleServer>();

Server-side authentication provider for SRP-6a protocol takes a user account repository instance. It's a custom class used to abstract away the user account storage from the authentication provider. Account repository is a component that implements the following interface:

/// <summary>
/// Account repository for the SRP-6a protocol implementation.
/// </summary>
public interface ISrpAccountRepository
{
	/// <summary>
	/// Finds the user account data by the given username.
	/// </summary>
	/// <param name="userName">Name of the user.</param>
	ISrpAccount FindByName(string userName);
}

/// <summary>
/// SRP-6a account data.
/// </summary>
public interface ISrpAccount
{
	/// <summary>
	/// Gets the name of the user.
	/// </summary>
	string UserName { get; }

	/// <summary>
	/// Gets the salt.
	/// </summary>
	string Salt { get; }

	/// <summary>
	/// Gets the password verifier.
	/// </summary>
	string Verifier { get; }
}

Storing and retrieving the user accounts is up to the application developer. The typical storage for the user accounts is a database table.