Skip to main content

GitHub Repository

Configuration

GitHub Access Token: Generate a classic token with the read:packages scope to access dependencies hosted on GitHub Package Repository.
.gradle/gradle.properties
savaGithubPackagesUsername=GITHUB_USERNAME
savaGithubPackagesPassword=GITHUB_TOKEN

Compile

./sava-vanity/compile.sh

Run

./sava-vanity/genKeys.sh --prefix="abc" --outDir=".keys"

Docker

Instead of running the local jlink binary, you can run a Docker image by passing the docker flag with the image name and tag. Build the image:
docker build --build-arg PROJECT=sava-vanity -t sava-vanity:local -f sava-vanity/Dockerfile .
Run it:
./sava-vanity/genKeys.sh --docker="sava-vanity:local" --prefix="abc" --outDir=".keys"
By default, the image is built only when it is not found locally. Pass the build flag to force a rebuild even if the image already exists:
./sava-vanity/genKeys.sh --docker="sava-vanity:local" --build --prefix="abc" --outDir=".keys"
When not using Docker, the local jlink binary image (./gradlew :sava-vanity:image) is built automatically when it has not been built yet. Pass the build flag to force a rebuild of the local binary image even if it already exists:
./sava-vanity/genKeys.sh --build --prefix="abc" --outDir=".keys"
An outDir is required so the generated keys are saved to disk; the host directory is created if necessary and bind-mounted into the container with write permissions so that generated keys are persisted on the host:
./sava-vanity/genKeys.sh --docker="sava-vanity:local" --prefix="abc" --outDir=".keys"

Args

  • A prefix and/or suffix must be provided.
  • outDir is required so the generated keys are saved to disk.
  • numThreads defaults to half of the systems CPU’s.
  • keyFileFormat controls the on-disk key file format and may be properties (default) or json.
  • Each thread will check every checkFound iterations if numKeys have been found.
  • p1337Letters allows alphabetic characters to be replaced by visually similar numbers.
  • 1337Numbers allows numbers to be replaced by visually similar alphabetic characters.
  • screen may be enabled to manage the session so that it can be re-attached if a remote session is disconnected.
    • ctrl+a -> d to detach
    • screen -r to re-attach

Run Control

  • jvmArgs=“-server -Xms64M -Xmx128M”
  • [d | docker | dockerImage]=
  • [b | build]=false
  • screen=0
  • [nt | numThreads]=
  • [nk | numKeys]=1
  • [kf | keyFormat]=“base64KeyPair”
  • [kff | keyFileFormat]=“properties”
  • [cf | checkFound]=131072
  • [ld | logDelay]=“5S”
  • [o | outDir]=‘.keys’ (required)
  • [sv | sigVerify]=false

Encryption

The generated secret key can be encrypted at rest by enabling the encrypt flag. The password is never passed on the command line or as a JVM system property (both of which are visible in process listings); it is supplied to the Java runtime only via the SAVA_VANITY_ENCRYPT_PASSWORD environment variable.
  • [e | encrypt]=false
  • [pw | password] — securely prompts for the password (with confirmation) and forwards it to the Java runtime via the environment variable. Implies encrypt=true.
  • [pe | passwordEnv]=ENV_VAR_NAME — reads the password from an already-exported environment variable for fully non-interactive runs. Implies encrypt=true.
If encrypt=true is set without password/passwordEnv, and the SAVA_VANITY_ENCRYPT_PASSWORD environment variable is not present, the application falls back to reading the password from the interactive Java Console.
# Securely prompt for the encryption password.
./sava-vanity/genKeys.sh --prefix="abc" --password

# Non-interactive: read the password from an existing environment variable.
export MY_VANITY_PASSWORD="..."
./sava-vanity/genKeys.sh --prefix="abc" --passwordEnv=MY_VANITY_PASSWORD

Key Derivation (KDF)

The password is run through a key derivation function before it is used to encrypt the secret. The kdf flag selects the function and the secret is always encrypted with AES-256/GCM. The KDF parameters can be customized; when they are omitted, hardened defaults are used.
  • [kdf]=argon2id — argon2id (memory-hard, the default) or pbkdf2 (PBKDF2WithHmacSHA512).
  • [kit | kdfIterations] — number of iterations. Applies to both pbkdf2 and argon2id.
  • [kmem | kdfMemoryKB] — Argon2id memory cost in KiB. Only valid with kdf=argon2id.
  • [kpar | kdfParallelism] — Argon2id parallelism (lanes). Only valid with kdf=argon2id.
Argon2id parameter tuning is all-or-nothing: either provide none of kdfMemoryKB, kdfParallelism and kdfIterations (to use the defaults) or provide all three. Because Argon2id is memory-hard, each concurrent derivation allocates kdfMemoryKB of heap (default 262144 KB / 256 MiB). When kdf=argon2id is selected, genKeys.sh automatically sizes the JVM heap to (kdfMemoryKB × numThreads) + 128 MiB so concurrent derivations do not exhaust the default heap. Passing your own --jvm args disables this auto-sizing.
# Use Argon2id (the default) with the hardened defaults.
./sava-vanity/genKeys.sh --prefix="abc" --password

# Use Argon2id with fully customized parameters (all three are required).
./sava-vanity/genKeys.sh --prefix="abc" --password --kdf=argon2id \
  --kdfMemoryKB=262144 --kdfParallelism=4 --kdfIterations=3

# Opt out of Argon2id and customize only the PBKDF2 iteration count.
./sava-vanity/genKeys.sh --prefix="abc" --password --kdf=pbkdf2 --kdfIterations=600000

Prefix

  • [p | prefix]=""
  • [pc | pCaseSensitive]=false
  • [pn | p1337Numbers]=true
  • [pl | p1337Letters]=true

Suffix

  • [s | suffix]=""
  • [sc | sCaseSensitive]=false
  • [sn | s1337Numbers]=true
  • [sl | s1337Letters]=true