Struct NonceClient

Source
pub struct NonceClient { /* private fields */ }
Expand description

Client-side nonce manager for generating signed requests.

The NonceClient is responsible for creating cryptographically signed requests that can be verified by a NonceServer. It provides a lightweight, stateless interface for generating nonces and signatures without requiring any database or persistent storage.

§Security Features

  • HMAC-SHA256 Signing: Uses industry-standard HMAC with SHA256 for signatures
  • UUID Nonces: Generates cryptographically random UUIDs for nonces
  • Timestamp Inclusion: Includes current timestamp to prevent old request replay
  • Stateless Design: No local state or storage required
  • Fully Customizable: All signature algorithms are defined by the application

§Usage Pattern

The typical usage pattern is:

  1. Create a client with a shared secret
  2. Generate signed requests with custom signature algorithms
  3. Send the signed request to the server for verification

§Example

use nonce_auth::NonceClient;
use hmac::Mac;

// Create a client with a shared secret
let client = NonceClient::new(b"my_shared_secret");

// Generate a signed request with custom signature
let protection_data = client.create_protection_data(|mac, timestamp, nonce| {
    mac.update(timestamp.as_bytes());
    mac.update(nonce.as_bytes());
    mac.update(b"custom_payload");
}).unwrap();

§Thread Safety

NonceClient is thread-safe and can be shared across multiple threads or used concurrently to generate multiple signed requests.

Implementations§

Source§

impl NonceClient

Source

pub fn new(secret: &[u8]) -> Self

Creates a new NonceClient with the specified secret key.

The secret key should be shared between the client and server and kept confidential. It’s used to generate HMAC signatures that prove the authenticity of requests.

§Arguments
  • secret - The secret key for HMAC signature generation. This should match the secret used by the server.
§Returns

A new NonceClient instance ready to generate signed requests.

§Security Considerations
  • Use a cryptographically strong secret key (at least 32 bytes recommended)
  • Keep the secret key confidential and secure
  • Use the same secret key on both client and server
  • Consider rotating secret keys periodically
§Example
use nonce_auth::NonceClient;

// Create with a strong secret key
let secret = b"my_very_secure_secret_key_32_bytes";
let client = NonceClient::new(secret);

// Or use a dynamically generated secret
let dynamic_secret = "generated_secret_from_key_exchange".as_bytes();
let client = NonceClient::new(dynamic_secret);
Source

pub fn create_protection_data<F>( &self, signature_builder: F, ) -> Result<ProtectionData, NonceError>
where F: FnOnce(&mut Hmac<Sha256>, &str, &str),

Generates protection data with custom signature algorithm.

This method provides complete flexibility to create protection data with any signature algorithm. The signature algorithm is defined by the closure which receives the MAC instance, timestamp, and nonce.

§Arguments
  • signature_builder - A closure that defines how to build the signature data
§Returns
  • Ok(ProtectionData) - Authentication data with custom signature
  • Err(NonceError) - If there’s an error in the cryptographic operations
§Example
use nonce_auth::NonceClient;
use hmac::Mac;

let client = NonceClient::new(b"shared_secret");
let payload = "request body";

// Create protection data with payload included in signature
let protection_data = client.create_protection_data(|mac, timestamp, nonce| {
    mac.update(timestamp.as_bytes());
    mac.update(nonce.as_bytes());
    mac.update(payload.as_bytes());
}).unwrap();
Source

pub fn generate_signature<F>( &self, data_builder: F, ) -> Result<String, NonceError>
where F: FnOnce(&mut Hmac<Sha256>),

Generates an HMAC-SHA256 signature with custom data builder.

This method provides maximum flexibility for signature generation by allowing applications to define exactly what data should be included in the signature through a closure.

§Arguments
  • data_builder - A closure that adds data to the HMAC instance
§Returns
  • Ok(String) - The hex-encoded HMAC signature
  • Err(NonceError) - If there’s an error in the cryptographic operations
§Example
use nonce_auth::NonceClient;
use hmac::Mac;

let client = NonceClient::new(b"shared_secret");

// Generate signature with custom data
let signature = client.generate_signature(|mac| {
    mac.update(b"timestamp");
    mac.update(b"nonce");
    mac.update(b"payload");
    mac.update(b"method");
}).unwrap();

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.