Skip to main content

Shield

Struct Shield 

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

EXPTIME-secure symmetric encryption.

Uses password-derived keys with PBKDF2 and encrypts using a SHA256-based stream cipher with HMAC-SHA256 authentication. Breaking requires 2^256 operations - no shortcut exists.

Version 2 adds replay protection and length obfuscation:

  • Timestamp validation prevents replay attacks
  • Random padding (32-128 bytes) obfuscates message length

Key separation: Derives separate subkeys for encryption and authentication to prevent cross-protocol attacks: enc_key = SHA256(key || 0x01), mac_key = SHA256(key || 0x02).

Key material is securely zeroized from memory when dropped.

Implementations§

Source§

impl Shield

Source

pub fn new(password: &str, service: &str) -> Self

Create a new Shield instance from password and service name.

§Arguments
  • password - User’s password
  • service - Service identifier (e.g., “github.com”)
§Example
use shield_core::Shield;
let shield = Shield::new("my_password", "example.com");
Source

pub fn with_key(key: [u8; 32]) -> Self

Create Shield with a pre-shared key (no password derivation).

Source

pub fn with_fingerprint( password: &str, service: &str, mode: FingerprintMode, ) -> Result<Self>

Create Shield with hardware fingerprinting (device-bound encryption).

Derives keys from password + hardware identifier, binding encryption to the physical device. Keys cannot be transferred to other hardware without the correct fingerprint.

§Arguments
  • password - User’s password
  • service - Service identifier (e.g., “github.com”)
  • mode - Fingerprint collection mode (Motherboard, CPU, or Combined)
§Example
use shield_core::{Shield, FingerprintMode};
let shield = Shield::with_fingerprint("password", "example.com", FingerprintMode::Combined)?;
§Errors

Returns error if hardware fingerprint cannot be collected.

§Security
  • Binding Strength: MEDIUM (hardware IDs are stable but replaceable)
  • Spoofability: LOW-MEDIUM (requires hardware access or VM manipulation)
  • Portability: NONE (keys are device-bound by design)
Source

pub fn with_max_age(self, max_age_ms: Option<u64>) -> Self

Set maximum message age for replay protection.

§Arguments
  • max_age_ms - Maximum age in milliseconds, or None to disable replay protection
Source

pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>>

Encrypt data (v2 format with replay protection and length obfuscation).

Returns: nonce(16) || ciphertext || mac(16)

Inner format: counter(8) || timestamp_ms(8) || pad_len(1) || random_padding(32-128) || plaintext

§Errors

Returns error if random generation fails.

Source

pub fn encrypt_with_key(key: &[u8; 32], plaintext: &[u8]) -> Result<Vec<u8>>

Encrypt with explicit key (v2 format). Derives separate enc/mac subkeys internally.

Source

pub fn decrypt(&self, encrypted: &[u8]) -> Result<Vec<u8>>

Decrypt and verify data (supports both v1 and v2 formats).

Automatically detects v2 format by timestamp range and applies replay protection if configured. Tries separated subkeys first, falls back to unified key for backward compatibility.

§Errors

Returns error if MAC verification fails, ciphertext is malformed, or message is expired.

Source

pub fn decrypt_with_key(key: &[u8; 32], encrypted: &[u8]) -> Result<Vec<u8>>

Decrypt with explicit key (no replay protection).

Source

pub fn decrypt_with_max_age( key: &[u8; 32], encrypted: &[u8], max_age_ms: Option<u64>, ) -> Result<Vec<u8>>

Decrypt with explicit max age for replay protection.

Source

pub fn decrypt_v1(&self, encrypted: &[u8]) -> Result<Vec<u8>>

Decrypt v1 format explicitly (for backward compatibility with legacy ciphertext).

Always uses v1 parsing: skip 8-byte counter prefix, no timestamp check.

Source

pub fn decrypt_v1_with_key(key: &[u8; 32], encrypted: &[u8]) -> Result<Vec<u8>>

Decrypt v1 format with explicit key (uses separated subkeys).

Trait Implementations§

Source§

impl Drop for Shield

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Zeroize for Shield

Source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the zeroization operation is not “optimized away” by the compiler.

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, 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.