Skip to content
/ srp Public

A Go implementation of the Secure Remote Password Protocol (SRP)

License

Notifications You must be signed in to change notification settings

fmitra/srp

Repository files navigation

Build Status Report Card codecov

srp

A Go implementation of the Secure Remote Password Protocol (SRP)

Overview

This package implements SRP as defined in RFC 2945 and RFC 5054.

RFC 2945: The SRP Authentication and Key Exchange System

RFC 5054: Using the Secure Remote Password (SRP) Protocol for TLS Authentication

Usage

This package exposes several methods defined in AuthClient and AuthServer interfaces to complete the authentication flow. It offers a default Client and Server set to use SHA256 as the hashing algorithm and the 4096 prime value group from RFC 5054 Section 3.2.

c, _ := NewDefaultClient("username", "password")
s, _ := NewDefaultServer()

You can pass your own hashing algorithm or prime value group as well.

g, _ := NewGroup(Group8192)
c, _ := NewClient(crypto.SHA512, g, "username", "password")
s, _ := NewServer(crypto.SHA512, g)

This package provides the tooling to enroll and validate a user. Using this library however will still require you to:

  • Securely store client submitted credentials during registration. This includes username, salt, verifier
  • Retreive user salt and verifier during authentication.

Authentication Overview

A detailed overview on authentication can be found on RFC 2945 Page 3. In general, we implement the following flow where:

  • a, A: Client ephemeral private and public key (*big.Int)
  • b, B: Server ephemeral private and public key (*big.Int)
  • K: PremasterKey (A shared key generated by both Client and Server (*big.Int)
  • M1: Client proof of K generation (*big.Int)
  • M2: Server proof of K generation (*big.Int)
Client                        Server
----------                    ----------
Calculate a, A
I, A              --------->
                              Calculate b, B
                  <---------  B, s
Calculate K, M1
M1                --------->  Calculate K, M2
                              Confirm M2
                  <---------  M2
Confirm M2

At each stage of the auth flow, client/server will receive/return several credentails (ex. salt, verifier, proof, public keys) to move forward with the premasterkey calculation.

Registration

  • Client generates username, salt, verifier
uname, salt, verifier, err := c.Enroll()
  • Server accepts credentials. Persisting this data is outside the scope of this package. The verifier value acts as the server's long term secret value for the user. It is never transmitted back after this.
isEnrolled := s.ProcessEnroll(uname, salt, verifier)

Authentication

  • Client generates a new public key and username used during enrollment
uname, cPubKey := c.Auth()
  • Server receives credentials from the client. On success, it will generate its own public key and return the salt used during registration.
# You will need to implement this
salt, verifier := RetrieveThisFromSomeStorage()

# On success we will receive the salt and ephemeral public key for the client
sPubKey, salt, err := s.ProcessAuth(uname, salt, cPubKey, verifier)
  • Client receives salt and ephemeral public key from server. It then generates proof of its identity to send back to the server.
cProof, err := c.ProveIdentity(sPubKey, salt)
  • Server receives the client's proof of identity. If valid, it will return it's own proof for the client.
sProof, err := s.ProcessProof(cProof)
  • If the server successfully validated the client proof, it will generate it's own proof that the client may validate.
isServerValid := c.IsProofValid(sProof)

Validation of both the server and client proof ensures that they both calculated the same PremasterKey. At this point you may authenticate the user or use the shared key as part of your authentication protocol.

Test

Tests rely on testify's assert library. It should install automatically if this project is stored outside of your GOPATH. If it is inside GOPATH, you first need to enable module support.

export GO111MODULE=on

Run tests

make test

Lint

golangci-lint is used for linting. To install (OSX)

brew install golangci/tap/golangci-lint

Run linter

make lint

About

A Go implementation of the Secure Remote Password Protocol (SRP)

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published