“Password” this crazy piece of string worth a lot, get a lot of attention but yet very hard to process & hide. Even with the multi-factor approach, it is crucial to design the first step right (which is what the user knows).
It becomes increasingly harder for the software systems to securely authenticate their users, process the sensitive password in a right & secure way. One of the most common approaches is,
Storing the hashed version of the password using algorithms like Argon2, bcrypt, etc and use it for authenticating the users. By now, this is the minimum baseline for handling sensitive secrets like password, anything below this (like as plain-text or encoded) means you are probably doing the bad thing, stop it, go back to safety!.
Hashed passwords offer a good trade-off between simplicity and security but for a piece of highly sensitive information or system it has its own drawbacks,
- It needed a trusted server to securely process & store the hashed passwords (which promises not to log passwords 😀)
- An attacker with a large password dictionary & a breached database can determine the user’s password
- An attacker can eavesdrop (MITM attack) communication between client and server and can acquire the password.
What we needed, in this case, is a strong Zero-knowledge proof (without transferring password) system that does mutual authentication on the client & server. Let's look at a shy and less popular implementation called Secure Remote Password (SRP)
Secure Remote Password (SRP)
SRP is a secure augmented password-authenticated key agreement (PAKE) protocol that solves the problem of exchanging secrets securely over an untrusted network.
It is a zero-knowledge proof protocol, where the server doesn’t have to store password equivalently information (hashed version), and clients can securely authenticate to the server. And an eavesdropper or man-in-the-middle cannot obtain any meaningful information to perform an attack. SRP offers great benefits such as,
- Can authenticate without needing to send the password over the network
- Resists from both active & passive attacks, such as MITM or brute-force dictionary attacks.
- Proves the identity of the server & client to each other and makes sure no imposter party is involved.
- Additionally offers a secure session encryption key, so the client & server can transmit encrypted data providing higher security on top of TLS.
How does it work?
SRP contains many layers and mathematical derivations. But in simple terms, it consists of three steps registration, authentication, and verification. Let's see how it works,
This is the first step in the process, in which the client transmits certain information for future authentication. so during signup, the client will,
- generates a random salt
- the client passes the username, password, and salt to a mathematical function (KDF) to derive x
- then it generates something called verifier, using the derived x and an SRP group (more on this later).
- Then it sends the verifier, salt, and the SRP group along with the username to the server and the server will store the verifier and salt for the user.
Client(username, verifier, salt) → Server stores (verifier, salt) for user
Let's look at the terms used,
Salt — a random string used during computation of the verifier
KDF — a key derivation function that will transform the password into a very large number eg: PBKDF etc.
SRP group — consists of one large prime number & a generator. you can choose between several groups eg: 1024 bit, 2048 bit, etc
Verifier — this is the random string generated out of x, and it's not the hashed version of the password, also it cannot be effectively used to guess the password.
Now that the registration is complete, the user is ready for authenticating with the server.
This is the interesting & confusing part, in order to prove that the user knows their password, the client & server exchange non-sensitive information to generates a key independently and use it for verification.
- The clients make a request to the server to get the salt & SRP group for the given username
- then it passes the username, password, salt to the KDF to derive x (same as during registration)
- it also generates a one-time ephemeral value a (private) and its counterpart A (public) using SRP group, were private a is kept in-memory and its public value A is sent to the server
The server while sending the salt back to the user,
- generates one-time ephemeral value b (private) its counter-part B (public) using the SRP group, stores the private value b in temporary storage, and sends the public value A to the client.
Client(username) → Server returns (salt, SRP group, B)
What’s just happened 🤯?
It sounds confusing, isn’t it? (x, a, b, A, B, KDF, verifier)! Honestly, it took a while for me to understand as well. In simple terms,
- The Password was not transmitted to the server
- Instead, the client & server exchanges A & B
- So a client with (x, a, B) and the server with (verifier, b, A) using different calculations can arrive at the same value, which is used as a session encryption key (trust the Math).
This is part of the authentication, in the previous step we just created the same session encryption key in both client & server-side without exchanging any sensitive information, but we haven’t verified that both parties have derived the same value (which is what we wanted out of all these fancy math). The verification flow looks like this,
- the client encrypts a message using the session encryption key and sends it to the server.
- the server decrypts the message and verifies it, if not verified, fails the authentication process.
- if verified successfully, the server encrypts a message using its session encryption key and sends its back to the client.
- the client decrypts the message and verifies it.
Thus the client & server both successfully verified that they know the user’s password and legit, and can now use the session encryption key as the symmetric encryption key to exchange encrypted messages. Cool 😎
SRP protocol consists of many calculations, back-and-forth communication between client & server, and complex terms to understand. Luckily since its an open protocol several implementations available to make life easier,
This is a demo application of how to register and authenticate a user with the Thinbus Secure Remote Password (SRP…
Simply clone the above project, and install the dependencies by running,
Note: you should have Node & NPM installed in your machine.
Then run the application locally,
you should see the server started message,
> node server.js
Node has started on port 8080
go to http://localhost:8080 in your browser,
Before authentication, we need to register the user, click
Register using SRP link from the main page,
Enter a username and password of your choice, and click submit. Let's look at the network request for registration,
As you can see in the Request payload, the password was never sent, instead, the client sends (username, salt, and verifier) to the server. This will be stored on the server-side and the verifier is never transmitted back again.
Head over to the main page & click
Login using SRP ,
Enter the same username & password and click Login. Let's look at this network request,
The first step is to retrieve the salt & server challenge B for the given username, so the first request will call
/challenge the endpoint which looks like this,
The server returns the salt, and also generate a one-time ephemeral pair (b, B) and returns the public value B in the response.
Then, the client computes the necessary value, and make the
As you can see the client sends the following information,
A — client’s one-time ephemeral public value
username — username
M1 — this is the encrypted message using the generated session key for the server to verify
So the server decrypts the M1 message and verifies it if successful then it generates M2 (encrypted message using its session key) and returns to the client for verification. So verification is mutual here. Finally, you get this,
Note: Neither the password nor the session key is transmitted in this communication.
SRP protocol offers the right amount of flexibility, strong security, and user convenience. So we don't have to reinvent the wheel and use SRP as the Strong password system, even a low entropy password that can be used securely.
— — If you are interested in similar stories, check out — —