Encryption and hashing library for dynamic algorithm resolution, eliminating the need of storing the algorithm metadata for decryption and hash comparison.
Note
GitHub and Maven packages will be available after Jun 2026, to use the library. For now clone the repository and install dependencies locally.
Main
API
Core
Encoded bytes are bytes produced by the algorithm and are wrapped with the AlgorithmOutput. Encoded bytes are in the following order:
- Algorithm type (1 byte) i.e: AES.
- Algorithm variant (1byte) i.e: GCM
- Metadata bytes (Optional) i.e: metadata length, initial vector, salt, etc.
- Main algorithm bytes (hash or encrypted bytes produced by the implementation)
Metadata bytes are optional and their presence depends on the algorithm implementation.
We will focus on the Encryption part, but hashing part is very similar.
First, lets install the core package and one of the Encryptors implementation. In this case we will use AES GCM, but you can create your own implementation or install other dependency.
<dependency>
<groupId>dev.ysdaeth.autocrypt</groupId>
<artifactId>j-autocrypt-core</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>dev.ysdaeth.autocrypt</groupId>
<artifactId>j-autocrypt-aes-gcm</artifactId>
<version>0.1</version>
</dependency>Now, lets create Cryptographic registry and register the AES GCM encryptor. Register method
accepts the Supplier<Encryptor>, but to keep example simple, we will pass instance reference to the object
and make the registry to wrap it with the supplier internally.
We can define own identifier that will be used by the encryptor.
AlgorithmIdentifier identifierAesGcm = new AlgorithmIdentifier( (byte) 0x01, (byte) 0x06 );
Encryptor aes = new EncryptorAesGcm(identifier);
CryptographicRegistry<Encryptor> registry = new CryptographicRegistry<>();
registry.register(aes);Tip
Algorithm identifier first byte should be the algorithm type, second byte the algorithm variant. You can create own identifiers, but take a look at Proposed identifiers
We already have the EncryptorRegistry, now we can inject it into the EncryptionManager. When encrypting, we need to specify the algorithm we want to use - we've already created it before. Encoded bytes contain identifier, metadata and encrypted bytes. We will take an advantage of it later.
EncryptionManager manager = new EncryptionManager(registry);
byte[] secret = "secret".getBytes();
Key secretKey = KeyGenerator.getInstance("AES").generateKey();
AlgorithmOutput output = manager.encrypt(secret, secretKey, identifierAesGcm);
byte[] encodedBytes = output.getEncoded();Finally, when we want to decrypt our data we can use encodedBytes to provide decryptor.
Here we wrap the encoded bytes with the AlgorithmOutput. Encoded bytes must follow rules of the Bytes encoding
AlgorithmOutput output = new AlgorithmOutput( encodedBytes );
byte[] decrypted = manager.decrypt(output, secretKey);Note
In this example we don't need to specify the AlgorithmIdentifier because it is already computed in our encoded bytes, along with metadata like the initial vector.
- Java 25
- Designed for OpenJDK
- AES GCM
- HMac Sha 224
- HMac Sha 256
- HMac Sha 384
- HMac Sha 512
- Sha 224
- Sha 256
- Sha 384
- Sha 512
- Argon2id
- Argon2i
- Argon2d
- Bcrypt
- RSA OAEP
New target list will be released after this one is completed