Crate srp6[−][src]
Expand description
An implementation of Secure Remote Password (SRP6) authentication protocol.
NOTE: Please do only use key length >= 2048 bit in production. You can do so by using Srp6_2048
or Srp6_4096
.
Usage
The usage example start on the server side. Client side interaction is marked explicit when needed.
1. A new user, welcome Bob
use srp6::*;
// this is happening on the client,
// the password is never send to the server at any time
let new_username: UsernameRef = "Bob";
let user_password: &ClearTextPassword = "secret-password";
let (salt_s, verifier_v) = Srp6_2048::default().generate_new_user_secrets(
new_username,
user_password
);
assert_eq!(salt_s.num_bytes(), Srp6_2048::KEY_LEN);
assert_eq!(verifier_v.num_bytes(), Srp6_2048::KEY_LEN);
// The server needs to persist,
// `new_username`, `salt_s` and `verifier_v` in a user database / pw file
NOTE: the password of the user will not be stored!
NOTE2: the salt and verifier will never be the same, they have a random component to it
2. A session handshake for Bob
On the server side
- when a user/client connects they would send their
Username
first - with the username the server will lookup their
Salt
andPasswordVerifier
from a user database or pw file - with this data the server would start the authentication with a
Handshake
send to the client - the server would also keep a
HandshakeProofVerifier
for this user in order to verify the proof he will get from the client
use srp6::*;
// the username is sent by the client
let user = mocked::lookup_user_details("Bob");
let srp = Srp6_2048::default();
let (handshake, proof_verifier) = srp.start_handshake(&user);
assert_eq!(handshake.s, user.salt);
assert_eq!(handshake.N, srp.N);
assert_eq!(handshake.g, srp.g);
assert_eq!(handshake.B.num_bytes(), Srp6_2048::KEY_LEN);
// TODO: next step: the client calculates proof
3. A Proof
that Bob is Bob
- with the handshake, Bob needs to create
Proof
that he is Bob - this
Proof
and hisPublicKey
will be sent to the server where it is verified
use srp6::*;
// this is entered by the user
let username = "Bob";
let bobs_password: &ClearTextPassword = "secret-password";
// this comes from the server
let handshake = mocked::handshake_from_the_server(username);
// the final proof calculation
let (proof, strong_proof_verifier) = handshake
.calculate_proof(username, bobs_password)
.unwrap();
// `proof` send this proof to the server
// `strong_proof_verifier` is kept for the final verification
4. Verify Proof
from Bob
- The client sends the proof (
[HandshakeProof
]) to the server - The server calculates his version of the Proof and compoares if they match
- On Success both parties have calculated a strong proof (
StrongProof
M2) and a session key (StrongSessionKey
K)
// this comes from the server
let username = "Bob";
let proof_verifier = mocked::stored_proof_verifier_from_step_2(username);
let proof_from_bob = mocked::bobs_proof();
let strong_proof = proof_verifier.verify_proof(&proof_from_bob);
assert!(strong_proof.is_ok());
let (strong_proof, session_key_server) = strong_proof.unwrap();
// `strong_proof` is sent back to bob
5. Bob verifies the host
- The client receivs the strong proof (
StrongProof
K) from the server - Bob calculates his own strong proof and verifies the both match
- On Success both parties have verified each other and have a shared strong proof (
StrongProof
M2) and a session key (StrongSessionKey
K)
use srp6::*;
let strong_proof_verifier = mocked::strong_proof_verifier_from_step_3();
let strong_proof = mocked::strong_proof_from_step_4_from_the_server();
let res = strong_proof_verifier.verify_strong_proof(&strong_proof);
assert!(res.is_ok());
Note on key length
this crate provides some default keys preconfigured and aliased. The modulus prime and genrator numbers are taken from RFC5054.
Further details and domain vocabolary
- You can find the documentation of SRP6 variables in a dedicated module.
- RFC2945 that describes in detail the Secure remote password protocol (SRP).
- RFC5054 that describes SRP6 for TLS Authentication
- check out the 2 examples that illustrates the srp authentication flow as well
Re-exports
pub use defaults::*;
Modules
default prime modulus and generator numbers taken from RFC5054 Appendix A, so they can be treated as vetted and safe.
A very brief summary of the papers and RFCs of SRP6 and SRP6a
Structs
Contains all variables needed for a successful session key generation provided by the server to the client
This is responsible for verifying a HandshakeProof
that is
provided by the client to the server
Main interaction point for the server
Verifies the StrongProof
provided by the server to the client
Username
and ClearTextPassword
used on the client side
User details composes Username
, Salt
and PasswordVerifier
in one struct
Enums
Traits
this trait provides a higher level api
An attempted conversion that consumes self
, which may or may not be
expensive.
Type Definitions
Clear text password p
as str
Refers to the modulus generator g
Refers to a multiplier parameter k
(k = H(N, g) in SRP-6a, k = 3 for legacy SRP-6)
Password Verifier is the users secret on the server side
Refers to a large safe prime called N
(N = 2q+1
, where q
is prime)
Refers to a private secret random number a (user), b (server)
Refers to M
and M1
Proof of server and client
Refers to a Public shared key called A (user), B (server)
encapsulates a Srp6Error
Refers to a User’s salt called s
Refers to the SessionKey S
Refers to M2
the hash of Proof
Refers to the StrongSessionKey K
Username I
as String
Username reference I
as &str