scramp: SCRAM Protocol Implementation
raw JSON → 1.4.8 verified Tue May 12 auth: no python install: verified quickstart: stale
scramp is a pure-Python implementation of the SCRAM (Salted Challenge Response Authentication Mechanism) authentication protocol. It supports various SCRAM mechanisms including SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-512, SCRAM-SHA3-512, and their channel-binding ('-PLUS') variants. The library is currently at version 1.4.8 (as of January 6, 2026) and maintains an active development status with moderate release cadence.
pip install scramp Common errors
error ModuleNotFoundError: No module named 'scramp' ↓
cause The 'scramp' library is not installed in the current Python environment.
fix
pip install scramp
error TypeError: a bytes-like object is required, not 'str' ↓
cause A Python string (`str`) was provided to a 'scramp' function or method that expects a byte string (`bytes`), often for sensitive data like passwords or salts.
fix
Encode the string to bytes, typically using
.encode('utf-8'). Example: client.set_password('mysecret'.encode('utf-8')) error scramp.exceptions.ScrampError: Authentication failed ↓
cause The SCRAM authentication exchange failed due to incorrect credentials (username, password), invalid proofs, or a violation of the authentication protocol steps.
fix
Verify the provided username, password, salt, and iteration count (N). Ensure both client and server are correctly following the SCRAM message exchange sequence and data integrity.
error ValueError: Auth mechanism 'SCRAM-SHA-128' not supported by server ↓
cause The client attempted to negotiate an authentication mechanism (e.g., 'SCRAM-SHA-128') that the 'scramp' server instance was not configured to support or did not advertise as available.
fix
Ensure that the client requests a mechanism that is present in the server's list of supported mechanisms, or configure the server to include the desired mechanism in its
mechanisms parameter during instantiation. Warnings
breaking Version 1.2.0 introduced backward-incompatible changes to the server-side API. This update modified how authentication information is handled to enable storing derived user data (e.g., in a database) and integrate with third-party hashing libraries like `passlib`. ↓
fix Review server-side implementations (e.g., `make_auth_info`, `build_server_first_message`) and adapt to the updated API, especially if custom authentication databases or hashing functions are used.
gotcha `ScramClient` selects the most secure mechanism from a provided list. To use channel-binding (`-PLUS`) variants, the `channel_binding` parameter (a tuple of name and data) must be explicitly provided during `ScramClient` initialization. If `channel_binding` is `None`, `-PLUS` mechanisms will be filtered out. ↓
fix When initializing `ScramClient`, pass `channel_binding=('tls-server-end-point', your_tls_data)` or similar if channel binding is desired for stronger security.
gotcha The package name `scramp` is easily confused with other Python libraries or projects (e.g., `scamp` for music, `SCAMP`/`pyscamp` for matrix profiles, `SCaMP` for metagenomics, `SCRAP` for RNA-seq, Scamp5d vision system). Ensure you are installing and importing `scramp` specifically for SCRAM protocol implementation. ↓
fix Always verify the PyPI project description and source URL to confirm you are using `scramp` for SCRAM authentication, not a similarly named library with different functionality.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.14s 18.8M
3.10 alpine (musl) - - 0.16s 18.8M
3.10 slim (glibc) wheel 1.7s 0.11s 19M
3.10 slim (glibc) - - 0.11s 19M
3.11 alpine (musl) wheel - 0.22s 20.9M
3.11 alpine (musl) - - 0.26s 20.9M
3.11 slim (glibc) wheel 1.7s 0.19s 21M
3.11 slim (glibc) - - 0.19s 21M
3.12 alpine (musl) wheel - 0.19s 12.7M
3.12 alpine (musl) - - 0.19s 12.7M
3.12 slim (glibc) wheel 1.8s 0.19s 13M
3.12 slim (glibc) - - 0.19s 13M
3.13 alpine (musl) wheel - 0.18s 12.4M
3.13 alpine (musl) - - 0.19s 12.3M
3.13 slim (glibc) wheel 1.6s 0.18s 13M
3.13 slim (glibc) - - 0.19s 13M
3.9 alpine (musl) wheel - 0.14s 18.3M
3.9 alpine (musl) - - 0.15s 18.3M
3.9 slim (glibc) wheel 1.8s 0.12s 19M
3.9 slim (glibc) - - 0.12s 19M
Imports
- ScramClient
from scramp import ScramClient - ScramMechanism
from scramp import ScramMechanism
Quickstart stale last tested: 2026-04-24
import os
from scramp import ScramClient, ScramMechanism
# --- Server Side Setup ---
username = "user@example.com"
password = os.environ.get('SCRAMP_TEST_PASSWORD', 'test_password') # In a real app, load from secure config
# Server mechanism (stores user's SCRAM data derived from password)
# In a real application, auth_info would be retrieved from a database for the given username.
server_mechanism = ScramMechanism(password=password)
server_auth_info = server_mechanism.make_auth_info(password) # Derived data to store/retrieve for user
print("Server: Initialized SCRAM mechanism and derived auth info.")
# --- Client Side Exchange ---
client = ScramClient(
mechanisms=['SCRAM-SHA-256'], # Client offers preferred mechanisms
username=username,
password=password
)
print(f"Client: Initialized SCRAM client for user '{username}'.")
# 1. Client sends initial message
client_first_message = client.build_client_first_message()
print(f"Client: Sending client-first-message: {client_first_message}")
# 2. Server receives client-first-message and builds server-first-message
# In a real server, 'server_auth_info' would be loaded from a DB based on 'username'
server_first_message = server_mechanism.build_server_first_message(
client_first_message, server_auth_info
)
print(f"Server: Sending server-first-message: {server_first_message}")
# 3. Client receives server-first-message and builds client-final-message
client_final_message = client.build_client_final_message(server_first_message)
print(f"Client: Sending client-final-message: {client_final_message}")
# 4. Server receives client-final-message and authenticates
server_final_message = server_mechanism.build_server_final_message(
client_final_message, server_auth_info
)
if server_mechanism.authenticated:
print("Server: Client authenticated successfully!")
print(f"Server: Sending server-final-message: {server_final_message}")
else:
print("Server: Authentication failed.")
# 5. Client receives server-final-message (for verification and channel binding)
try:
client.verify_server_final_message(server_final_message)
print("Client: Server final message verified (authentication successful from client perspective).")
except ValueError as e:
print(f"Client: Server final message verification failed: {e}")