Class SecretValue
- All Implemented Interfaces:
AutoCloseable
Lifecycle
SecretValue is AutoCloseable so callers can scope
a secret to a try-with-resources block. The close() hook
calls destroy(), which overwrites the internal char[]
with zeros. Once destroyed, every accessor throws
IllegalStateException (CWE-226).
JVM memory honesty
The JVM offers no perfect way to scrub heap memory: garbage
collection may have copied the backing array to other regions before
destruction; strings produced by an unrelated caller may keep a copy
elsewhere. SecretValue provides best-effort defence: it owns
the backing array, never converts to String internally, and
zeros temporary UTF-8 buffers it constructs. Callers should still
keep secret lifetimes as short as possible.
Interoperability
Phase 1a/1b providers accept char[] for historical reasons.
asChars() returns a defensive copy the caller owns; they
remain responsible for zeroing it after use. The package also exposes
asUtf8Bytes() for providers that need a byte[]
(bcrypt, scrypt). Both methods refuse access after destruction.
-
Method Summary
Modifier and TypeMethodDescriptionchar[]asChars()Returns a defensive copy of the held characters.byte[]Returns the UTF-8 encoding of the held characters in a fresh byte array.voidclose()Alias fordestroy()soSecretValuecan be used in try-with-resources blocks.voiddestroy()Zeros the internal storage.booleanWhetherdestroy()has been called.intlength()Number of characters held.static SecretValueofChars(char[] source) Builds aSecretValuefrom a caller-ownedchar[].static SecretValueConvenience overload forStringinputs.toString()Returns a redacted shape:"SecretValue[length=N, destroyed=false]".
-
Method Details
-
ofChars
Builds aSecretValuefrom a caller-ownedchar[]. The caller's array is defensively copied; the original array remains the caller's responsibility (and is typically zeroed immediately afterwards). -
ofString
Convenience overload forStringinputs. Note thatStringinstances are immutable and may be retained by the JVM string pool; preferofChars(char[])for genuinely sensitive material. -
length
public int length()Number of characters held. Reported even after destruction so callers can debug lifecycle issues without recovering the value. -
isDestroyed
public boolean isDestroyed()Whetherdestroy()has been called. -
asChars
public char[] asChars()Returns a defensive copy of the held characters. The caller owns the returned array and should zero it after use.- Throws:
IllegalStateException- if the secret was already destroyed
-
asUtf8Bytes
public byte[] asUtf8Bytes()Returns the UTF-8 encoding of the held characters in a fresh byte array. The internalCharBufferand intermediateByteBufferbacking array are zeroed before returning.- Throws:
IllegalStateException- if the secret was already destroyed
-
destroy
public void destroy()Zeros the internal storage. Subsequent accessor calls throwIllegalStateException. Callingdestroyon an already-destroyed secret is a no-op. -
close
public void close()Alias fordestroy()soSecretValuecan be used in try-with-resources blocks.- Specified by:
closein interfaceAutoCloseable
-
toString
-