Giter VIP home page Giter VIP logo

srp6-variables's Introduction

SRP-6 Variables

Build Status Build status Codacy Badge Coverage Status

Maven Central javadoc

LoC Hits-of-Code

A Java library of cryptographic primitives required to implement the SRP-6 protocol, built with Caesar.

Motivation

Some of the existing open source SRP-6 Java libraries include:

What I've found is that such libraries are not easy to extend.

Most of them work only with big-endian byte array representations and some of them aren't compliant with RFC 5054.

With that in mind, I decided to create a library of basic building blocks (SRP-6 Variables) that one can use to implement the protocol.

Usage

In order to use this library, you must first settle on a couple of constants:

  • group parameters
  • source of randomness
  • hash function
  • byte order

For the purposes of demonstration, the following constants will be used throughout this page:

// Group parameters
SRP6IntegerVariable N =
    new SRP6CustomIntegerVariable(
        new Hex(
            "EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B"
          + "9EA2314C 9C256576 D674DF74 96EA81D3 383B4813 D692C6E0"
          + "E0D5D8E2 50B98BE4 8E495C1D 6089DAD1 5DC7D7B4 6154D6B6"
          + "CE8EF4AD 69B15D49 82559B29 7BCF1885 C529F566 660E57EC"
          + "68EDBC3C 05726CC0 2FD4CBF4 976EAA9A FD5138FE 8376435B"
          + "9FC61D2F C0EB06E3"
        ),
        ByteOrder.BIG_ENDIAN
    );
SRP6IntegerVariable g =
    new SRP6CustomIntegerVariable(
        BigInteger.valueOf(2)
    );

// Source of randomness
SecureRandom rng = new SecureRandom();

// Hash function
ImmutableMessageDigest imd =
    new ImmutableMessageDigest(
        MessageDigest.getInstance("SHA-256")
    );

// Byte order
ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;

Creating records

Say we want to create a new record of the form <I, s, v> for user "alice" with password "password123":

Bytes I = new PlainText("alice");
Bytes P = new PlainText("password123");

Bytes s = Bytes.wrapped(rng.generateSeed(32));

SRP6IntegerVariable x = new SRP6PrivateKey(imd, s, I, P, byteOrder);
SRP6IntegerVariable v = new SRP6Verifier(N, g, x);

Client side authentication

This example is based on the optimized message ordering, as described here:

  1. First, client sends his or her username (I) to the server.

  2. The server then responds with: N, g, s and B.

  3. Client then performs the following computations:

    SRP6IntegerVariable x = new SRP6PrivateKey(imd, s, I, P, byteOrder);
    SRP6IntegerVariable a = new SRP6RandomEphemeral(rng, N);
    SRP6IntegerVariable A = new SRP6ClientPublicKey(N, g, a);
    SRP6IntegerVariable u = new SRP6ScramblingParameter(imd, A, B, N, byteOrder);
    SRP6IntegerVariable k = new SRP6Multiplier();
    // for SRP-6a:
    // SRP6IntegerVariable k = new SRP6Multiplier(imd, N, g, byteOrder);
    SRP6IntegerVariable S = new SRP6ClientSharedSecret(N, g, k, B, x, u, a);
    Bytes K = new SessionKey(imd, S, byteOrder);
    Bytes M1 = new ClientSessionProof(imd, N, g, I, s, A, B, K, byteOrder);

    and responds with A and M1:

    try {
        byte[] bufferA = A.bytes(byteOrder).asArray();
        byte[] bufferM1 = M1.asArray();
        // send over 'bufferA' and 'bufferM1' to the server
        // ...
    } catch (IllegalStateException e) {
        // Immediately abort SRP-6 login!
        // Under no circumstances show the server A and M1!
    }
  4. Finally, the server responds with M2 and client checks its validity:

    Bytes cM2 = new ServerSessionProof(imd, N, A, M1, K, byteOrder);
    try {
        if (cM2.equals(M2)) {
            // Authentication successful!
        } else {
            // Authentication failed: server proof mismatch.
        }
    } catch (IllegalStateException e) {
         // Immediately abort SRP-6 login!
    }

Server side authentication

This example is based on the optimized message ordering, as described here:

  1. First, the server receives client username (I).

  2. Then the server performs the following computations:

    // lookup and fetch the record by I -> <I, s, v>
    SRP6IntegerVariable b = new SRP6RandomEphemeral(rng, N);
    SRP6IntegerVariable k = new SRP6Multiplier();
    // for SRP-6a:
    // SRP6IntegerVariable k = new SRP6Multiplier(imd, N, g, byteOrder);
    SRP6IntegerVariable B = new SRP6ServerPublicKey(N, g, k, v, b);

    and responds with: N, g, s, and B:

    try {
        byte[] bufferN = N.bytes(byteOrder).asArray();
        byte[] buffer_g = g.bytes(byteOrder).asArray();
        byte[] buffer_s = s.asArray();
        byte[] bufferB = B.bytes(byteOrder).asArray();
        // send over 'bufferN', 'buffer_g', 'buffer_s', 'bufferB' to the client
        // ...
    } catch (IllegalStateException e) {
        // Immediately abort SRP-6 login!
        // Under no circumstances show the client N, g, s, or B.
    }
  3. Client then responds with A and M1 and the server performs these additional computations and responds with M2:

    SRP6IntegerVariable u = new SRP6ScramblingParameter(imd, A, B, N, byteOrder);
    SRP6IntegerVariable S = new ServerSharedSecret(N, A, v, u, b);
    Bytes K = new SessionKey(imd, S, byteOrder);
    Bytes sM1 = new ClientSessionProof(imd, N, g, I, s, A, B, K, byteOrder);
    try { 
        if (sM1.equals(M1)) {
            // Authentication successful!
            Bytes M2 = new ServerSessionProof(imd, N, A, M1, K, byteOrder);
            byte[] buffer_M2 = M2.asArray();
            // send over 'bufferM2' to the client
            // ...
        } else {
            // Authentication failed: client proof mismatch.
        }
    } catch (IllegalStateException e) {
        // Immediately abort SRP-6 login!
        // Under no circumstances show the client M2.
    }

Releases

Use the release script with the following arguments:

  1. release - the next release version

  2. snapshot - the next snapshot version

  3. dryRun (optional) - if set to true, the changes will not be pushed to the remote repository

Example:

./release.sh 0.1.1 0.1.2-SNAPSHOT

srp6-variables's People

Contributors

glusk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

srp6-variables's Issues

Add WoW Test Vectors

Add WoW authentication SRP-6 test vectors, dumped from a private server session.

SRP-6 variables todo list

Implement:

  • u Random scrambling parameter -- #16
  • A,B Public ephemeral values -- #22 #24
  • a,b Private ephemeral values -- #26
  • x Private key (derived from p and s) -- #12
  • v Password verifier -- #9
  • k Multiplier parameter (k = H(N, g) in SRP-6a, k = 3 for legacy SRP-6) -- #30

  • M1,M2 Proofs of session key -- #49 #43
  • S Shared secret -- #35 #37
  • K Session key -- #41

  • Basic usage README section with code examples -- #52

Motivation

Some of the existing open source SRP-6 Java libraries include:

What I've found is that such libraries are not easy to extend.

Most of them work only with big-endian byte array representations and some of them aren't compliant with RFC 5054.

With that in mind, I decided to create a library of basic building blocks (SRP-6 Variables) that one can use to implement the protocol.

Fix SRP6RandomEphemeral

SRP6RandomEphemeral was first implemented as part of #26.

Remove synchronized from method declaration. In project Loom, a synchronized block or a method blocks the underlying platform thread. Assuming SRP6 authentication runs in a virtual thread, this could potentially slow the application.

Fix the typo in the code comment.

Don't use exceptions for flow control

Currently, we have the following conde snippet as part of our README.md:

if (!(cM2.equals(M2))) {
    throw new SRP6Exception("Server proof mismatch!");
}

This is not an exceptional behaviour. It's perfectly normal that an SRP6 authentication fails (ie, wong credentials). Let's not use exceptions for flow control in our examples. Fix the example; re-think where to throw an exception and what type.

Should be done after/with #78.

Repo badges

Lets add the following:

  • Travis build status
  • Codacy project report
  • Coveralls coverage
  • LoC + HoC

Add 2 more Bytes implementations

We want something like this:

// SRP6IntegerVariable x = ...
// SRP6IntegerVariable y = ...

// bytes of x in BIG_ENDIAN byte order
Bytes b1 = new SRP6IntegerVariableBytes(x, ByteOrder.BIG_ENDIAN);
// bytes of x in BIG_ENDIAN byte order, zero-padded to the byte length of y
Bytes b2 = new SRP6IntegerVariableBytes(x, ByteOrder.BIG_ENDIAN, y);

instead of in addtion to this:

// SRP6IntegerVariable x = ...
Bytes b1 = x.bytes(ByteOrder.BIG_ENDIAN);
Bytes b1 = x.bytes(ByteOrder.BIG_ENDIAN, 32);

in order to enhance object composition and defer execution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.