srp6
A pure Python implementation of the Secure Remote Password protocol (SRP version 6a) with GSA mode support.
Overview
SRP (Secure Remote Password) is a password-authenticated key exchange protocol that allows secure authentication without transmitting the password over the network. This implementation follows RFC 5054 and includes support for GSA (Grand Slam Authentication) mode.
Features
- Pure Python - No external dependencies, uses only Python standard library
- Multiple Key Sizes - Support for 1024 to 8192-bit primes from RFC 5054
- GSA Mode - Compatible with GSA authentication services
- Hash Cash - Includes proof-of-work implementation for rate limiting
- Type Hints - Full type annotation support
Installation
pip install srp6
Usage
Basic SRP Client
from srp6 import SRPClient, pbkdf2_sha256
# Create client with username
client = SRPClient(b"user@example.com")
# Derive password using PBKDF2 (typically from server's salt)
password = b"secret_password"
salt = b"server_provided_salt"
derived_password = pbkdf2_sha256(password, salt, iterations=10000)
client.password = derived_password
# Get public ephemeral to send to server
A = client.get_public_ephemeral()
# After receiving server's salt and public ephemeral B:
# Generate client proof M1
M1 = client.generate(salt=server_salt, server_public=server_B)
# Get session key for encrypted communication
session_key = client.session_key
Using Different Prime Groups
from srp6 import SRPClient, SRP_1024, SRP_4096
# Use 1024-bit prime (faster, less secure)
client_1024 = SRPClient(b"user", group=1024)
# Use 4096-bit prime (slower, more secure)
client_4096 = SRPClient(b"user", group=4096)
# Or pass the group directly
client = SRPClient(b"user", group=SRP_4096)
Hash Cash (Proof of Work)
from srp6 import generate_hashcash, verify_hashcash
# Generate proof of work
bits = 11 # Difficulty level (number of leading zero bits)
challenge = "server_challenge_string"
hashcash = generate_hashcash(bits, challenge)
# Verify proof of work
is_valid = verify_hashcash(hashcash, bits)
API Reference
SRPClient
class SRPClient:
def __init__(
self,
username: bytes,
a: int | None = None,
group: SRPGroup | int | None = None
):
"""
Initialize SRP client.
Args:
username: The username/identity bytes
a: Optional private ephemeral value (for testing)
group: SRP group - SRPGroup instance, bit size (1024/2048/4096), or None for default (2048)
"""
Properties:
password- Set the derived password (from PBKDF2)session_key- Get the computed session key KM- Get the client proof M1group- Get the SRP group being used
Methods:
get_public_ephemeral()- Get client's public ephemeral Agenerate(salt, server_public)- Generate client proof M1generate_m2()- Generate M2 for verification
Prime Groups
All groups from RFC 5054 (1024 to 8192 bits):
SRP_1024- 1024 bits (128 bytes) - Legacy, not recommendedSRP_1536- 1536 bits (192 bytes) - LegacySRP_2048- 2048 bits (256 bytes) - Standard (default)SRP_3072- 3072 bits (384 bytes) - Enhanced securitySRP_4096- 4096 bits (512 bytes) - High securitySRP_6144- 6144 bits (768 bytes) - Very high securitySRP_8192- 8192 bits (1024 bytes) - Maximum security
Utility Functions
# Hashing
hash_sha256(data: bytes) -> bytes
pbkdf2_sha256(password: bytes, salt: bytes, iterations: int, dklen: int = 32) -> bytes
# Byte conversions
bytes_to_int(b: bytes) -> int
int_to_bytes(n: int, length: int | None = None) -> bytes
to_hex(data: bytes) -> str
from_hex(hex_str: str) -> bytes
GSA Mode
This implementation supports GSA (Grand Slam Authentication) mode, which differs from standard SRP-6a in the following ways:
-
Identity not included in x computation - The password verifier x is computed as
H(salt || H(":" || password))instead ofH(salt || H(I || ":" || password)) -
Generator padding - The generator g is padded to N_BYTES when computing
H(g)for the M1 proof -
No padding for A, B, S - The public ephemerals A and B, and the shared secret S are NOT padded in their respective computations
Protocol Details
Notation
N- Large safe prime (N = 2q+1, where q is prime)g- Generator modulo Nk- Multiplier parameter:k = H(N || pad(g))s- User's saltI- Usernamep- Cleartext passwordH()- One-way hash function (SHA-256)x- Private key derived from password and saltv- Password verifier stored on servera,b- Secret ephemeral valuesA,B- Public ephemeral valuesS- Premaster secretK- Session keyM1,M2- Proofs
Registration (One-Time Setup)
x = H(s || H(I || ":" || p)) # Private key
v = g^x % N # Verifier (stored on server)
The server stores: (I, s, v). The password p is never stored.
Authentication Handshake
Client Server
------ ------
| |
| -------- I, A = g^a % N ------> |
| |
| <------- s, B = kv + g^b % N -- |
| |
| u = H(pad(A) || pad(B)) | u = H(pad(A) || pad(B))
| x = H(s || H(I || ":" || p)) |
| S = (B - kg^x)^(a + ux) % N | S = (Av^u)^b % N
| K = H(S) | K = H(S)
| |
| -------- M1 = H(...) ----------> | (verify M1)
| |
| (verify M2) <------ M2 = H(...) -- |
| |
| [Session key K established] |
Client Calculations
- Generate random
a, computeA = g^a % N - Receive
s,Bfrom server - Compute
u = H(pad(A) || pad(B)) - Compute
k = H(N || pad(g)) - Derive
x = H(s || H(I || ":" || p)) - Compute
S = (B - k * g^x)^(a + u*x) % N - Compute session key
K = H(S) - Compute proof
M1 = H(H(N) XOR H(g) || H(I) || s || A || B || K)
Server Calculations
- Look up
s,vfor userI - Generate random
b, computeB = k*v + g^b % N - Receive
Afrom client - Compute
u = H(pad(A) || pad(B)) - Compute
S = (A * v^u)^b % N - Compute session key
K = H(S) - Verify client proof
M1 - Compute server proof
M2 = H(A || M1 || K)
Security Safeguards
The protocol aborts if any of these conditions occur:
- Client aborts if
B % N == 0(malicious server) - Client aborts if
u == 0(compromised exchange) - Server aborts if
A % N == 0(malicious client) - Server aborts if client proof
M1is invalid
Protocol Flow Diagram
Client Server
------ ------
| |
| -------- username, A --------> |
| |
| <------- salt, B ------------- |
| |
| -------- M1 (proof) ---------> |
| |
| <------- M2 (verification) --- |
| |
| [Session key K established] |
Examples
See the examples directory for complete working examples:
- 01_signup.py - User registration, generating salt and verifier
- 02_authentication.py - Complete authentication handshake
- 03_different_groups.py - Using different prime group sizes
- 04_hashcash.py - Hash cash proof-of-work for rate limiting
Run examples:
python examples/01_signup.py
python examples/02_authentication.py
References
- RFC 2945 - The SRP Authentication and Key Exchange System
- RFC 5054 - Using SRP for TLS Authentication
- Stanford SRP Homepage
License
MIT License - see LICENSE for details.
Release files for srp6 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| srp6-0.1.1.tar.gz | 12.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| srp6-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.1 kB
Release files / srp6-0.1.1.tar.gz
| Download URL | srp6-0.1.1.tar.gz |
|---|---|
| Size | 12.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9deca3d8d1592c65a442cc491e0fbf9f75280877cbcca4f74d7ca12129e5241c
|
|
BLAKE2b-256 checksum How to use checksums |
f81bc001742d1bf99834e59e1367a62c4c03139c4291ac751b3632fd166521c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.
Transparency logRelease files / srp6-0.1.1-py3-none-any.whl
| Download URL | srp6-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0acb5a909168c8cf2d572e7786427a292193de392cbe771a3b0cb66d9021bf08
|
|
BLAKE2b-256 checksum How to use checksums |
519167c0d3b0e4b3e0b5cc196a31f9f0e8c6c3844e855ffe0792866564505db6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.
Transparency log