Crate nonce_auth

Source
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 requests
  • NonceServer: Server-side verification and nonce management
  • ProtectionData: The data structure exchanged between client and server
  • NonceError: 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§

nonce

Structs§

ProtectionData
Authentication data for nonce-based request verification.