Class Secret

java.lang.Object
dev.enola.common.secret.Secret
All Implemented Interfaces:
Processor<char[]>, AutoCloseable

public final class Secret extends Object implements AutoCloseable, Processor<char[]>
Secret 🔑 is a wrapper around an auto-cleaned char[]. It's intended to hold sensitive character data like passwords, pass phrases, access tokens like API keys and similar credentials, often related to configuration. It is cleared from memory when the Secret is close()d.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Secret(char[] data)
    Creates a Secret instance from a character array.
    Secret(String data)
    Deprecated.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Clears the sensitive data by filling the internal char array with zeros.
    <R> R
    map(Function<char[],R> mapping)
    Safely processes the sensitive data using a function.
    void
    process(Consumer<char[]> consumer)
    Safely processes the sensitive data using a consumer.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Secret

      public Secret(char[] data)
      Creates a Secret instance from a character array. The provided array is copied internally. The input array argument is then zeroed out immediately.
      Parameters:
      data - The sensitive character data.
    • Secret

      @Deprecated public Secret(String data)
      Deprecated.
      Deprecated constructor. Prefer using Secret(char[]) instead, if you can somehow originally work with a char array (think e.g. Console.readPassword()) already, to avoid using String all together.
      Parameters:
      data - String
  • Method Details

    • process

      public void process(Consumer<char[]> consumer)
      Safely processes the sensitive data using a consumer. A copy of the internal char array containing the secret data is passed to the consumer for immediate use. Its content is cleared again immediately after. This is the preferred and secure way to use the secret data, as it prevents creating long-lived copies or String objects outside the controlled scope.
      Specified by:
      process in interface Processor<char[]>
      Parameters:
      consumer - The consumer to process the char array.
      Throws:
      IllegalStateException - if the Secret instance has already been close()}.
    • map

      public <R> R map(Function<char[],R> mapping)
      Safely processes the sensitive data using a function. A copy of the internal char array containing the secret data is passed to the function for immediate use. Its content is cleared again immediately after. This is the preferred and secure way to use the secret data, as it prevents creating long-lived copies or String objects outside the controlled scope.

      Do not copy the secret data within the mapping if you can avoid it! When you really must, e.g. because you need to pass it to an existing less secure API which does not offer a (functional) "on-demand" alternative, then use secret.map(String::new).

      Specified by:
      map in interface Processor<char[]>
      Parameters:
      mapping - The function to process the char array.
      Throws:
      IllegalStateException - if the Secret instance has already been close()}.
    • close

      public void close()
      Clears the sensitive data by filling the internal char array with zeros. This method is automatically called when using try-with-resources. It is idempotent; calling it multiple times has no additional effect after the first call. The process(Consumer) and map(Function) methods will throw an IllegalStateException if invoked after this method.
      Specified by:
      close in interface AutoCloseable