| secrecy | shrouded | notes |
|---|---|---|
Secret<String> |
ShroudedString |
dedicated type |
Secret<Vec<u8>> |
ShroudedBytes |
dedicated type |
Secret<T> |
Shroud<T> |
generic wrapper |
.expose_secret() |
.expose() |
shorter name |
CloneableSecret |
.try_clone() |
returns Result |
SerializableSecret |
.expose() + manual ser |
no Serialize impl |
secrecy:
use secrecy::{Secret, ExposeSecret};
let password = Secret::new("hunter2".to_string());
let value: &str = password.expose_secret().as_str();shrouded:
use shrouded::{ShroudedString, Expose};
let password = ShroudedString::new("hunter2".to_string()).unwrap();
let value: &str = password.expose();- Fallible constructors.
ShroudedString::new()returnsResultbecause memory protection (mlock, guard pages) can fail.Secret::new()is infallible. - No Serialize. secrecy allows opt-in serialization via
SerializableSecret. shrouded has noSerializeimpl at all — call.expose()and serialize the inner value explicitly. - Fallible clone.
try_clone()returnsResultbecause each clone allocates new protected memory with mlock. secrecy'sClone(viaCloneableSecret) is infallible. - Guarded access.
expose_guarded()temporarily unlocks memory via mprotect and re-locks it when the guard is dropped. secrecy has no equivalent. - Extra protections. shrouded adds mlock, guard pages, and core dump exclusion on top of zeroize-on-drop.
| memsec | shrouded | notes |
|---|---|---|
malloc<T>() + mlock() |
Shroud<T>::new() |
lifecycle is automatic |
allocarray<T>(n) |
ShroudedArray<N> |
fixed-size |
| raw pointer access | .expose() / .expose_mut() |
safe API |
memzero() + munlock() + free() |
automatic on Drop |
memsec:
use memsec::{mlock, munlock, malloc, free, memzero};
unsafe {
let ptr: *mut u8 = malloc(32).unwrap();
mlock(ptr, 32);
// ... use ptr ...
memzero(ptr, 32);
munlock(ptr, 32);
free(ptr);
}shrouded:
use shrouded::{ShroudedBytes, Expose};
let secret = ShroudedBytes::new_with(32, |buf| {
// initialize buf
}).unwrap();
let data: &[u8] = secret.expose();
// Zeroized, munlocked, and freed on drop- Safe API. memsec requires
unsafefor most operations. shrouded's public API is entirely safe. - Automatic lifecycle. shrouded manages alloc, mlock, guard pages, zeroize, munlock, and free as a single unit. memsec requires you to call each step manually.
- No libsodium. shrouded calls OS APIs (mlock, mprotect, VirtualLock) directly. memsec depends on libsodium on some platforms.
- Policy control.
Policy::Strictturns protection failures into errors.Policy::BestEffort(default) falls back gracefully. memsec operations returnOptionorboolwith no configurable behavior.
| secstr | shrouded | notes |
|---|---|---|
SecStr |
ShroudedString or ShroudedBytes |
SecStr wraps Vec<u8>, not necessarily UTF-8 |
SecVec<T> |
ShroudedBytes / Shroud<T> |
|
.unsecure() |
.expose() |
|
.unsecure_mut() |
.expose_mut() |
|
SecStr::from("...") |
ShroudedString::new(s) |
returns Result |
SecStr::new(vec) |
ShroudedBytes::from_slice(&mut v) |
zeroizes source |
secstr:
use secstr::SecStr;
let secret = SecStr::from("hunter2");
let value: &[u8] = secret.unsecure();shrouded (as string):
use shrouded::{ShroudedString, Expose};
let secret = ShroudedString::new("hunter2".to_string()).unwrap();
let value: &str = secret.expose();shrouded (as bytes):
use shrouded::{ShroudedBytes, Expose};
let mut data = b"hunter2".to_vec();
let secret = ShroudedBytes::from_slice(&mut data).unwrap();
let value: &[u8] = secret.expose();- Fallible constructors. shrouded returns
Result; secstr constructors are infallible. - Choose your type.
SecStrwrapsVec<u8>regardless of content. UseShroudedStringfor text (UTF-8 validated) orShroudedBytesfor raw bytes. - Source zeroization.
ShroudedBytes::from_slice()zeroizes the input slice. secstr does not zeroize the source. - Guard pages + mprotect. shrouded adds guard pages around allocations and
supports automatic re-locking via
expose_guarded(). secstr has neither. - Explicit failure handling.
Policy::Strictturns mlock failures into errors. secstr silently falls back when mlock fails. - Serde. secstr supports optional Serialize + Deserialize. shrouded supports
Deserialize only — serialize by calling
.expose()on the inner value.