Srp

Hex.pmDocsBuild StatusCoverage Status

Secure Remote Password Protocol implementation in elixir.

SRP provides an implementation of the Secure Remote Password Protocol presented on The SRP Authentication and Key Exchange System, Using the Secure Remote Password (SRP) Protocol for TLS Authentication and The Secure Remote Password Protocol.

The protocol provides a way to do zero-knowledge authentication between client and servers. By using the SRP protocol you can:

Installation

The package can be installed by adding srp to your list of dependencies in mix.exs:

def deps do
  [
    {:srp, "~> 0.1.0"}
  ]
end

Usage

Checkout the full documentation for a complete usage.

Signing up

After the user provides his username and password, the client must generate a password verifier. Then it must send to the server:

username = "alice"
password = "password123"

identity = SRP.new_identity(username, password)
%SRP.IdentityVerifier{username: username, salt: salt, password_verifier: password_verifier} =
  SRP.generate_verifier(identity)

# Send to the server -> username + salt + password_verifier
# Server stores the information

Logging in

Authenticating a user on the server involves multiple steps.

  1. The client sends to the server the username.
  2. The server finds the password verifier and salt for that username. Then it generates a ephemeral key pair and sends back to the client the salt and the public key.
# Find the record for the given username
# Load from the database the password_verifier, and the salt
key_pair = SRP.server_key_pair(password_verifier)

# Send back to the client -> key_pair.public + salt

If the username does not exist the server can send a fake value. It is important to not reveal if an username is registered on the system or not. An attacker could use the login to find the registered usernames and try a dictionary attack specific for those users.

  1. The client generates a key pair and a client proof of identity. Then the client sends to the server the proof and the client’s public key.
# receives from the server the server_public_key and the salt.

identity = SRP.new_identity(username, password)
key_pair = SRP.client_key_pair()
proof = SRP.client_proof(identity, salt, key_pair, server_public_key)

# Send to the server -> proof + server_public_key
  1. Server verify client proof then build its own proof of identity. Then sends back the server’s proof.
valid? = SRP.valid_client_proof?(client_proof, password_verifier, server_key_wpair, client_public_key)

if valid? do
  # Send back to client the server's proof -> server_proof
else
  # Send back unauthorized
end
  1. The client receives the server’s proof and validates it. This step can be skipped if you don’t feel the need to verify the server’s identity.
identity = SRP.new_identity(username, password)
valid? = SRP.valid_server_proof?(server_proof, identity, salt, client_key_pair, server_public_key)

From now on is to safe to create a new session between the client and server.

License

Apache License, Version 2.0 © Thiago Santos