SRPTools
SRPTools is a Python library designed for implementing Secure Remote Password (SRP) authentication, a robust password-authenticated key agreement protocol (PAKE). It provides tools for both client and server sides to perform secure password-based authentication and key exchange over an insecure network. The current version is 1.0.1, with an infrequent release cadence indicating a stable and mature codebase.
Common errors
-
srptools.SRPException: Invalid public key 'B'
cause The client or server exchanged an invalid public key (A or B), or a step in the protocol was out of order, leading to a cryptographic mismatch.fixReview the order of operations in your SRP authentication flow. Ensure public keys are correctly generated, transmitted, and processed by the respective `start_authentication` and `process` methods. Check that context parameters (username, password, N, g, H) are identical on both client and server up to the point of key exchange. -
Authentication Failed: Session keys do not match.
cause The derived session keys (K) on the client and server sides do not match, indicating a failure in the key exchange or verification process. This could be due to incorrect input parameters (salt, verifier, public keys) or a tampered exchange.fixDouble-check that the `salt` and `verifier` used by the server correctly correspond to the `username` and `password` used by the client. Ensure that the public keys `A` and `B` are transmitted without modification and that the `process()` methods are called with the correct counterparts. Any mismatch in shared secrets or parameters will cause key divergence.
Warnings
- gotcha The `.process()` methods of `SRPClientSession` and `SRPServerSession` can raise `SRPException` under certain circumstances, indicating a failure in the SRP protocol flow (e.g., invalid public keys, incorrect proofs).
- gotcha When interoperating with other SRP implementations (e.g., in other languages or libraries like `pysrp`), ensure that both sides use compatible SRP-6a parameters, hashing algorithms, and key derivation functions. Slight variations in implementation details can lead to authentication failures.
- deprecated Although `srptools` supports Python 2 and 3, Python 2 is end-of-life. Continued development on Python 2 compatible codebases may expose projects to security vulnerabilities or lack of support.
Install
-
pip install srptools
Imports
- SRPContext
from srptools import SRPContext
- SRPClientSession
from srptools import SRPClientSession
- SRPServerSession
from srptools import SRPServerSession
- constants
from srptools import constants
Quickstart
from srptools import SRPContext, SRPServerSession, SRPClientSession
# User credentials
username = 'alice'
password = 'password123'
# Step 1: Server stores salt and verifier for a user
context = SRPContext(username, password)
salt, verifier = context.create_salted_verification_key()
print(f"Server stores -> Salt: {salt}, Verifier: {verifier}")
# --- Client side operations ---
client_session = SRPClientSession(context)
client_public_key = client_session.start_authentication()
print(f"Client sends -> Public Key A: {client_public_key}")
# --- Server side operations ---
# Server retrieves stored salt and verifier for the username
server_session = SRPServerSession(context, salt, verifier)
server_public_key = server_session.start_authentication(client_public_key)
print(f"Server sends -> Public Key B: {server_public_key}")
# --- Client side operations (receives B from server) ---
client_key = client_session.process(server_public_key)
print(f"Client computed -> Session Key K: {client_key}")
print(f"Client sends -> Proof M: {client_session.M}")
# --- Server side operations (receives Client Proof M from client) ---
server_key = server_session.process(client_session.M)
print(f"Server computed -> Session Key K: {server_key}")
# Verify client proof on server
if client_session.M == server_session.M:
print("Server: Client proof (M) matches. Authentication in progress.")
# Verify session keys match
if client_session.K == server_session.K:
print("Server: Session keys (K) match. Authentication successful.")
else:
print("Server Error: Session keys do not match.")
else:
print("Server Error: Client proof (M) does not match.")
# Server sends its proof (HAMK) to the client
print(f"Server sends -> Proof HAMK: {server_session.HAMK}")
# --- Client side operations (receives Server Proof HAMK from server) ---
if client_session.verify_session(server_session.HAMK):
print("Client: Server proof (HAMK) verified. Mutual authentication complete.")
else:
print("Client Error: Server proof (HAMK) verification failed.")