Encryption
Encryption turns sensitive strings into ciphertext that only your application can read, using a secret application key. Use it for cookie payloads, stored secrets, and any value that must remain opaque at rest or in transit through untrusted layers.
Artifact: org.konaframework:kona-auth (org.konaframework.security.Encrypter). AuthServiceProvider binds an Encrypter when app.key is set.
Application key
Section titled “Application key”The key is 32 raw bytes, usually stored as base64:… in config:
| Source | Notes |
|---|---|
Config app.key |
Read by Encrypter.fromConfig / AuthServiceProvider |
| Environment | Commonly mirrored as APP_KEY into that config key in your bootstrap |
Generate with grind (recommended for apps)
Section titled “Generate with grind (recommended for apps)”From your application directory:
./grind key:generate # write APP_KEY into .env./grind key:generate --show # print a key without writing./grind key:generate --force # overwrite in production without promptingkona new already embeds a random APP_KEY in the generated .env. Use key:generate when you copied .env.example by hand, rotated a key, or need to print a key for a secrets manager (--show). Full flag behavior: grind key:generate.
Generate in code
Section titled “Generate in code”import org.konaframework.security.Encrypter
val key = Encrypter.generateKey() // "base64:...."String key = Encrypter.generateKey();Put it in config before boot (or ensure .env / config/ seeds app.key):
.configure { it.set("app.key", Encrypter.generateKey()) }app.configure(config -> config.set("app.key", Encrypter.generateKey()));Never commit real production keys. Rotate carefully — ciphertext encrypted with the old key will not decrypt after rotation unless you re-encrypt. Use ./grind key:generate (with --force in production) when rotating the key stored in .env.
Encrypt and decrypt
Section titled “Encrypt and decrypt”val encrypter = app.resolve(Encrypter::class.java)// or: Encrypter.fromBase64Key(app.config.getString("app.key")!!)
val cipher = encrypter.encryptString("user@example.com")val plain = encrypter.decryptString(cipher)Encrypter encrypter = app.resolve(Encrypter.class);String cipher = encrypter.encryptString("user@example.com");String plain = encrypter.decryptString(cipher);Algorithm: AES-256-GCM. The payload is Base64-encoded JSON with Base64 fields iv, value, and tag.
Creating an encrypter manually
Section titled “Creating an encrypter manually”val fromConfig = Encrypter.fromConfig(app.config)val fromKey = Encrypter.fromBase64Key("base64:…")val fromBytes = Encrypter(ByteArray(32) /* exactly 32 bytes */)Encrypter.fromConfig(app.getConfig());Encrypter.fromBase64Key("base64:…");new Encrypter(keyBytes); // length must be 32Failure modes
Section titled “Failure modes”| Situation | Exception |
|---|---|
Missing app.key in fromConfig |
EncryptionException — “No application encryption key has been specified.” |
| Wrong key length / bad Base64 | EncryptionException — unsupported cipher or incorrect key length |
| Tampered or wrong-key ciphertext | EncryptionException — could not decrypt |
AuthServiceProvider with blank/invalid key |
Encrypter left unbound; resolve later after you set a valid key |
EncryptionException is unchecked — catch it at boundaries where you accept untrusted ciphertext.
When to encrypt
Section titled “When to encrypt”- Values you would not want readable in logs, cookies, or database columns
- Session cookie payloads when using the cookie session driver in non-local environments (combine with session configuration)
For JSON-serializable values use encrypt(value) / decrypt(payload, MyType::class.java) (Jackson). Prefer encryptString / decryptString for raw strings.
Do not use encryption as a substitute for password hashing. Passwords belong with Hash / bcrypt.