An open API service indexing awesome lists of open source software.

https://github.com/fmitra/srp

A Go implementation of the Secure Remote Password Protocol (SRP)
https://github.com/fmitra/srp

srp

Last synced: 6 months ago
JSON representation

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

Awesome Lists containing this project

README

          

[![Build Status](https://travis-ci.org/fmitra/srp.svg?branch=master)](https://travis-ci.org/fmitra/srp) [![Report Card](https://goreportcard.com/badge/github.com/fmitra/srp)](https://goreportcard.com/badge/github.com/fmitra/srp) [![codecov](https://codecov.io/gh/fmitra/srp/branch/master/graph/badge.svg)](https://codecov.io/gh/fmitra/srp)

# 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](https://tools.ietf.org/html/rfc2945)

[RFC 5054: Using the Secure Remote Password (SRP) Protocol for TLS Authentication](https://tools.ietf.org/html/rfc5054)

## 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](https://tools.ietf.org/html/rfc5054#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](https://tools.ietf.org/html/rfc2945).
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
```