Giter Site home page Giter Site logo

node-srp's Introduction

build status

SRP - Secure Remote Password

Implementation of the SRP Authentication and Key Exchange System and protocols in Secure Remote Password (SRP) Protocol for TLS Authentication

SRP is an interactive protocol which allows a server to confirm that some client knows a password, and to derive a strong shared session key, without revealing what the password is to an eavesdropper. In addition, the server does not hold the actual password: instead it stores a "verifier" created by the client. If the server's private data is revealed (by a server compromise), the verifier cannot be used directly to impersonate the client.

This module provides both client and server implementations of SRP-6a for node.js. They are interoperable with Mozilla Identity-Attached Services

Installation

npm install srp

or git clone this archive and run npm install in it.

Running Tests

Run npm test.

Tests include vectors from:

How to use it

First, you must decide on the "parameters". This module provides a variety of pre-packaged parameter sets, at various levels of security (more secure parameters take longer to run). The "2048"-bit parameters are probably fairly secure for the near future. Both client and server must use the same parameters.

var params = srp.params["2048"];

Each client will have a unique "identity" string. This is typically a username or email address. Clients will also use a unique "salt", which can be randomly generated during account creation. The salt is generally stored on the server, and must be provided to the client each time they try to connect.

Note that all APIs accept and return node.js Buffer objects, not strings.

Client Setup: Account Creation

The client feeds their identity string, password, and salt, into computeVerifier. This returns the Verifier buffer. The Verifier must be delivered to the server, typically during a "create account" process. Note that the Verifier can be used to mount a dictionary attack against the user's password, so it should be treated with care (and delivered securely to the server).

var verifier = srp.computeVerifier(params, salt, identity, password);
createAccount(identity, verifier);

The server should store the identity, salt, and verifier in a table, indexed by the identity for later access. The server will provide the salt to anyone who asks, but should never reveal the verifier to anybody.

Login

Later, when the client wants to connect to the server, it starts by submitting its identity string, and retrieving the salt.

Then the client needs to create a secret random string called secret1, using srp.genKey(). The protocol uses this to make sure that each instance of the protocol is unique.

Then, create a new srp.Client instance with parameters, identity, salt, password, and secret1.

The client must then ask this object for the derived srpA value, and deliver srpA to the server.

srp.genKey(function(secret1) {
    var c = new srp.Client(params, salt, identity, password, secret1);
    var srpA = c.computeA();
    sendToServer(srpA);
});

Meanwhile, the server is doing something similar, except using the Verifier instead of the salt/identity/password, and using its own secret random string.

srp.genKey(function(secret2) {
    var s = new srp.Server(params, verifier, secret2);
    var srpB = s.computeB();
    sendToClient(srpB);
});

When the client receives the server's srpB value, it stuffs it into the Client instance. This allows it to extract two values: M1 and K.

c.setB(srpB);
var M1 = c.computeM1();
sendToServer(M1);
var K = c.computeK();

M1 is a challenge value, created by the client and delivered to the server. After accepting the client's A value, the server can check M1 to determine whether or not the client really knew the password. The server can also obtain its own K value.

s.setA(srpA)
s.checkM1(M1); // throws error if wrong
var K = s.computeK();

If the password passed into srp.Client() is the same as the one passed into srp.computeVerifier(), then the server will accept M1, and the K on both sides will be the same.

K is a strong random string, suitable for use as a session key to encrypt or authenticate subsequent messages.

If the password was different, then s.checkM1() will throw an error, and the two K values will be unrelated random strings.

The overall conversation looks like this:

Client:                             Server:
 p = params["2048"]                  p = params["2048"]
 s1 = genKey()                       s2 = genKey()
 c = new Client(p,salt,id,pw,s1)     s = new Server(p,verifier,s2)
 A = c.computeA()            A---->  s.setA(A)
 c.setB(B)                <-----B    B = s.computeB()
 M1 = c.computeM1()         M1---->  s.checkM1(M1) // may throw error
 K = c.computeK()                    K = s.computeK()

What a "Session" Means

Basic login can be done by simply calling s.checkM1(): if it doesn't throw an exception, the client knew the right password. However, by itself, this does not bind knowledge of the password to anything else. If the A/B/M1 values were delivered over an insecure channel, controlled by an attacker, they could simply wait until M1 was accepted, and then take control of the channel.

Delivering these values over a secure channel, such as an HTTPS connection, is better. If the HTTP client correctly checks the server certificate, and the certificate was correctly issued, then you can exclude a man-in-the-middle attacker.

The safest approach is to create a secure channel with the generated session key K, using it to encrypt and authenticate all the messages which follow.

API Reference

Module contents:

  • params[]
  • table of parameter sets. Pass a property from this object into the Client and Server constructors.
  • genKey(numBytes, callback)
  • async function to generate the ephemeral secrets passed into the Client and Server constructors.
  • computeVerifier(params, salt, identity, password) -> V
  • produces a Verifier, which should be given to the server during account creation. The Verifier will be passed into the Server constructor during login.
  • Client(params, salt, identity, password, secret1) -> c
  • constructor for the client-side of SRP. secret1 should come from genKey(). The Client object has the following methods:
  • Server(params, verifier, secret2) -> s
  • constructor for the server-side of SRP. secret2 should come from genKey(). If the Server object must be persisted (e.g. in a database) between protocol phases, simply store secret2 and re-construct the Server with the same values. The Server object has the following methods:

Client methods:

  • computeA() -> A
  • produce the A value that will be sent to the server.
  • setB(B)
  • this accepts the B value from the server. M1 and K cannot be accessed until setB() has been called.
  • computeM1() -> M1
  • produce the M1 key-confirmation message. This should be sent to the server, which can check it to make sure the client really knew the correct password. setB must be called before computeM1.
  • computeK() -> K
  • produce the shared key K. If the password and verifier matched, both client and server will get the same value for K. setB must be called before computeK.

Server methods:

  • computeB() -> B
  • produce the B value that will be sent to the client.
  • setA(A)
  • this accepts the A value from the client. checkM1 and computeK cannot be called until setA has been called.
  • checkM1(M1)
  • this checks the client's M1 key-confirmation message. If the client's password matched the server's verifier, checkM1() will complete without error. If they do not match, checkM1() will throw an error.
  • computeK() -> K
  • produce the shared key K. setA must be called before computeK.

Resources

License

MIT

node-srp's People

Contributors

alexmax avatar ckarlof avatar dannycoates avatar heyvito avatar jedp avatar warner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-srp's Issues

Bignum error

Hi,

When I try making "npm install srp" it gives me an error
../bignum.cc:206:36: error: unknown type name 'Arguments'; did you mean 'v8::internal::Arguments'? static Handle<Value> Upowm(const Arguments& args);

Is the package still maintained? If not I'm willing to fork it but I would like to discuss with the package authors.

Regards.

Is this implementation outdated?

I understand this repo may not be maintained as it has not been updated since 2015, however was wondering security-wise if the SRP standard implementation has changed since then. I see that this is version SRP-6a which appears to be the latest on http://srp.stanford.edu/design.html, just wondering though.

use 'bignum' instead of 'bigint' to make dependency builds easier

@dannycoates has a patch to switch node-srp away from the "bigint" library in favor of the "bignum" library. This makes it possible to use node-srp with a simple "npm install". The "bigint" library depends upon having a pre-installed libgmp available on the system, whereas "bignum" apparently gets its math routines from OpenSSL, which is usually installed along with node itself.

bdc71ec is a patch which makes this change.

salt should be a string

One suggestion: "salt" is usually a string, not an integer. It should be UTF-8 -encoded into bytes (in a Buffer) before use.

Wiki changes

FYI: The following changes were made to this repository's wiki:

  • defacing spam has been removed

  • the wiki has been disabled, as it was not used

These were made as the result of a recent automated defacement of publically writeable wikis.

wtf /confirm response is 11MB

The response from /confirm is about 11MB. Apart from being utterly grody, this seems to cause intermittent test failures.

Confusing; the res.json responses in the confirm route do not, in any way obvious to me, inject any big chunks of data into the response.

CODE_OF_CONDUCT.md file missing

As of January 1 2019, Mozilla requires that all GitHub projects include this CODE_OF_CONDUCT.md file in the project root. The file has two parts:

  1. Required Text - All text under the headings Community Participation Guidelines and How to Report, are required, and should not be altered.
  2. Optional Text - The Project Specific Etiquette heading provides a space to speak more specifically about ways people can work effectively and inclusively together. Some examples of those can be found on the Firefox Debugger project, and Common Voice. (The optional part is commented out in the raw template file, and will not be visible until you modify and uncomment that part.)

If you have any questions about this file, or Code of Conduct policies and procedures, please reach out to [email protected].

(Message COC001)

Is this abandonware?

It appears this has been abandoned. Can you officially abandon it and recommend a better project?

Implement safeguard checks

From stanford design doc:

The two parties also employ the following safeguards:

  1. The user will abort if he receives B == 0 (mod N) or u == 0.
  2. The host will abort if it detects that A == 0 (mod N).
  3. The user must show his proof of K first. If the server detects that the user's proof is incorrect, it must abort without showing its own proof of K.

Support scrypt into SRP6a in order to avoid weak password storage

The default key material storage of SRP is considered to be weak (see Solar Designer here http://lists.randombit.net/pipermail/cryptography/2015-March/007121.html) .

For this reason we suggest, following discussion on randombit cryptography mailing list, to integrate scrypt as an additional custom hashing method to SRP as described by Alfonso De Gregorio (see http://lists.randombit.net/pipermail/cryptography/2015-March/007123.html) .

It's suggest to use the the following scrypt library This ticket ishttps://github.com/dchest/scrypt-async-js (by Solar designer, see http://lists.randombit.net/pipermail/cryptography/2015-March/007117.html).

By improving SRP authentication, bundling it with scrypt KDF, the authentication protocol would also feature strong password storage server side.

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.