Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fernet for Java

Maven Central

A dependency-free Java 17 implementation of the Fernet specification. It provides authenticated symmetric encryption for arbitrary byte arrays, optional token expiry, authenticated timestamp extraction, and key rotation.

Requirements

  • Java 17 or newer
  • No runtime dependencies

Installation

<dependency>
  <groupId>dev.ercan</groupId>
  <artifactId>fernet</artifactId>
  <version>1.0.0</version>
</dependency>

Basic usage

Load the key from persistent secret storage during normal application startup:

String key = secretManager.get("fernet-key");

Encrypt and decrypt UTF-8 text:

import dev.ercan.fernet.Fernet;

Fernet fernet = Fernet.of(key);

String token = fernet.encryptUtf8("secret message");
String message = fernet.decryptUtf8(token);

For binary data, use encrypt(byte[]) and decrypt(String).

Key provisioning

Create a key once during provisioning, store its encoded value, and reuse that same value on every application start:

import dev.ercan.fernet.FernetKey;

FernetKey generatedKey = FernetKey.generate();
String valueToPersist = generatedKey.encoded();

FernetKey.generate() does not persist the key. Do not call it on each startup: replacing or losing the key makes all tokens created with the previous key permanently undecryptable.

Token expiry

Pass a Duration when decrypting to enforce a maximum token age:

import java.time.Duration;

byte[] plaintext = fernet.decrypt(token, Duration.ofMinutes(15));

An expired token, an invalid signature, malformed input, invalid padding, and an unsupported token version all produce the same InvalidTokenException. This intentionally avoids exposing which validation stage failed. Fernet timestamps have one-second precision; a token exactly as old as its TTL is accepted. When a TTL is supplied, tokens more than 60 seconds in the future are rejected to account for clock skew.

The authenticated creation time can be read with:

Instant createdAt = fernet.extractTimestamp(token);

Key rotation

Place the newest key first and retain older keys only for the required migration window:

import dev.ercan.fernet.MultiFernet;

MultiFernet keyRing = MultiFernet.of(currentKey, previousKey);

String newToken = keyRing.encryptUtf8("uses the current key");
String plaintext = keyRing.decryptUtf8(tokenFromEitherKey);
String rotated = keyRing.rotate(tokenFromPreviousKey);

rotate authenticates and decrypts with the first matching key, then creates a token with the primary key and a fresh IV. It preserves the original creation timestamp.

Security notes

  • Fernet keys are encryption keys, not passwords. Generate them once with FernetKey.generate() during provisioning and store the encoded value in a secret manager; do not derive keys by padding or truncating user passwords.
  • Anyone holding a key can both create and read tokens. Fernet does not provide asymmetric signatures or authorization.
  • The creation timestamp is authenticated but visible in plaintext as part of the Fernet format.
  • Fernet is not a password-hashing scheme. Use a dedicated password hashing algorithm for stored passwords.
  • Prefer short, explicit TTLs where replay risk matters, and remove fallback keys after the rotation window.

See SECURITY.md for reporting security issues.

Build and compatibility

mvn verify

The test suite covers the official Fernet generate.json, verify.json, and invalid.json acceptance vectors, binary and UTF-8 round trips, TTL/clock-skew boundaries, authenticated-field mutations, concurrent use, and MultiFernet rotation.

Contributing

Contributions are welcome! Feel free to fork the repo, submit pull requests or open issues.

License

Released under the MIT License.

About

A dependency-free Java 17 implementation of the Fernet symmetric authenticated encryption specification.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages