Expand description
§Nonce Auth
A Rust library for secure nonce-based authentication that prevents replay attacks.
This library provides a complete solution for implementing nonce-based authentication in client-server applications. It uses HMAC-SHA256 signatures and SQLite for persistent nonce storage to ensure that each request can only be used once.
§Features
- HMAC-SHA256 Signing: Cryptographic signing of requests using shared secrets
- Replay Attack Prevention: Each nonce can only be used once
- Time Window Validation: Requests outside the time window are rejected
- Context Isolation: Nonces can be scoped to different business contexts
- SQLite Persistence: Automatic nonce storage and cleanup
- Async Support: Fully asynchronous API design
- Client-Server Separation: Clean separation of client and server responsibilities
§Quick Start
§Basic Usage
use nonce_auth::{NonceClient, NonceServer};
use std::time::Duration;
use hmac::Mac;
// Initialize the database
NonceServer::init().await?;
// Create client and server with shared secret
let secret = b"shared_secret_key";
let client = NonceClient::new(secret);
let server = NonceServer::new(secret, None, None);
// Client generates authentication data with custom signature
let protection_data = client.create_protection_data(|mac, timestamp, nonce| {
mac.update(timestamp.as_bytes());
mac.update(nonce.as_bytes());
})?;
// Server verifies the authentication data with matching signature algorithm
match server.verify_protection_data(&protection_data, None, |mac| {
mac.update(protection_data.timestamp.to_string().as_bytes());
mac.update(protection_data.nonce.as_bytes());
}).await {
Ok(()) => println!("Authentication verified successfully"),
Err(e) => println!("Verification failed: {e}"),
}§With Context Isolation
use nonce_auth::{NonceClient, NonceServer};
use hmac::Mac;
let client = NonceClient::new(b"secret");
let server = NonceServer::new(b"secret", None, None);
let protection_data = client.create_protection_data(|mac, timestamp, nonce| {
mac.update(timestamp.as_bytes());
mac.update(nonce.as_bytes());
})?;
// Same nonce can be used in different contexts
server.verify_protection_data(&protection_data, Some("api_v1"), |mac| {
mac.update(protection_data.timestamp.to_string().as_bytes());
mac.update(protection_data.nonce.as_bytes());
}).await?;
server.verify_protection_data(&protection_data, Some("api_v2"), |mac| {
mac.update(protection_data.timestamp.to_string().as_bytes());
mac.update(protection_data.nonce.as_bytes());
}).await?;§Database Configuration
The SQLite database location can be configured using the NONCE_AUTH_DB_PATH environment variable:
# Use a specific file
export NONCE_AUTH_DB_PATH="/path/to/nonce_auth.db"
# Use in-memory database (for testing)
export NONCE_AUTH_DB_PATH=":memory:"If not set, it defaults to nonce_auth.db in the current directory.
§Architecture
The library is designed with clear separation between client and server responsibilities:
NonceClient: Lightweight client for generating signed requestsNonceServer: Server-side verification and nonce managementProtectionData: The data structure exchanged between client and serverNonceError: Comprehensive error handling for all failure modes
Re-exports§
pub use nonce::NonceClient;pub use nonce::NonceConfig;pub use nonce::NonceError;pub use nonce::NonceServer;
Modules§
Structs§
- Protection
Data - Authentication data for nonce-based request verification.