logo

Module srp::client

source · []
Expand description

SRP client implementation.

Usage

First create SRP client struct by passing to it SRP parameters (shared between client and server).

You can use SHA1 from SRP-6a, but it’s highly recommended to use specialized password hashing algorithm instead (e.g. PBKDF2, argon2 or scrypt).

use crate::srp::groups::G_2048;
use sha2::Sha256; // Note: You should probably use a proper password KDF

let client = SrpClient::<Sha256>::new(&G_2048);

Next send handshake data (username and a_pub) to the server and receive salt and b_pub:


let mut a = [0u8; 64];
// rng.fill_bytes(&mut a);
let a_pub = client.compute_public_ephemeral(&a);
let (salt, b_pub) = server_response();

Process the server response and create verifier instance. process_reply can return error in case of malicious b_pub.


let private_key = (username, password, salt);
let verifier = client.process_reply(&a, username, password, salt, b_pub);

Finally verify the server: first generate user proof, send it to the server and verify server proof in the reply. Note that verify_server method will return error in case of incorrect server reply.


let client_proof = verifier.proof();
let server_proof = send_proof(client_proof);
verifier.verify_server(&server_proof).unwrap();

key contains shared secret key between user and the server. You can extract shared secret key using key() method.


verifier.key();

For user registration on the server first generate salt (e.g. 32 bytes long) and get password verifier which depends on private key. Send username, salt and password verifier over protected channel to protect against Man-in-the-middle (MITM) attack for registration.


let pwd_verifier = client.compute_verifier(username, password, salt);
send_registration_data(username, salt, &pwd_verifier);

Structs

SRP client state before handshake with the server.

SRP client state after handshake with the server.