Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
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
npm install srp
or git clone
this archive and run npm install
in it.
Run npm test
.
Tests include vectors from:
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.
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.
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()
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.
Module contents:
params[]
genKey(numBytes, callback)
computeVerifier(params, salt, identity, password) -> V
Client(params, salt, identity, password, secret1) -> c
Server(params, verifier, secret2) -> s
Client
methods:
computeA() -> A
setB(B)
computeM1() -> M1
computeK() -> K
Server
methods:
computeB() -> B
setA(A)
checkM1(M1)
computeK() -> K
MIT
FAQs
Secure Remote Password (SRP)
The npm package srp receives a total of 25 weekly downloads. As such, srp popularity was classified as not popular.
We found that srp demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.