Abstracted cryptographic library for straightforward & hassle-free cryptographic operations for JVM applications.
This library compliments with Java's JCE but does not necessarily aim for 1:1 functionality & compatibility in certain cases, this library is in some form opinionated but tries to offer customizablility as much as possible.
-
Bouncy Castle Security Provider (Configurable)
-
Symmetric Encryption (AES, ChaCha20, etc.)
-
Message Digests (MD5, SHA, SHA3, etc.)
-
MACs (HMAC, Poly1305 etc.)
-
and more to be implemented...
Minimum requirements to use the library:
- Kotlin 1.8+
- Java 11+
Modules | Description | Links |
---|---|---|
Core utilities for the library. (Internal use) | API | |
Data encryption using symmetric ciphers. (AES, ChaCha20, etc.). | API | |
Cryptographic hash functions (SHAs, MD5s, etc.). | API | |
Data integrity and authentication using MACs. | API |
implementation("io.github.jhdcruz:kipher-$module:$version")
<depenedencies>
<dependency>
<groupId>io.github.jhdcruz</groupId>
<artifactId>kipher-$module</artifactId>
<version>$version</version>
</dependency>
</depenedencies>
Using Snapshots
Look at module's gradle.properties
to check for latest snapshot version.
repositories {
mavenCentral()
// add snapshot repo
maven {
url("https://s01.oss.sonatype.org/content/repositories/snapshots")
}
}
dependencies {
implementation("io.github.jhdcruz:kipher-$module:0.2.0-SNAPSHOT")
}
<project>
<repositories>
<repository>
<id>sonatype-snapshots</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.github.jhdcruz</groupId>
<artifactId>kipher-$module</artifactId>
<version>0.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
[!WARNING]
Snapshots should be considered unstable and contains breaking changes, they are primarily for testing purposes, and not for production use.
import io.github.jhdcruz.kipher.symmetric.aes.AesGCM
fun main() {
val encryptionUtils = AesGCM()
val data = "sample data".encodeToByteArray()
val tag = "sample aad".encodeToByteArray()
// named parameters are recommended, but optional
val encrypted = encryptionUtils.encrypt(
data = message,
tag = tag,
// optional `key` parameter
) // returns Map of [data, key, tag]
val decrypted = encryptionUtils.decrypt(encrypted)
// or, manually:
val decrypted = encryptionUtils.decrypt(
encrypted = encrypted.getValue("data"),
key = encrypted.getValue("key")
tag = encrypted.getValue("tag")
)
println(decryptedPass.toString())
}
import io.github.jhdcruz.kipher.symmetric.aes.AesGCM;
import java.util.Map;
public class Main {
public static void main(String[] args) {
AesGCM encryptionUtils = new AesGCM();
byte[] data = "Hello World".getBytes();
Map<String, byte[]> encrypted = encryptionUtils.encrypt(data);
byte[] val = encryptionUtils.decrypt(encrypted);
// or
byte[] val = encryptionUtils.decrypt(
encrypted.get("data"),
encrypted.get("key")
encrypted.get("tag")
);
System.out.println(new String(val)); // outputs "Hello World"
}
}
import io.github.jhdcruz.kipher.symmetric.aes.AesCBC
fun main() {
val encryptionUtils = AesCBC()
val data = "sample data".encodeToByteArray()
val secretKey: ByteArray = encryptionUtils.generateKey(128) // should be a valid one
val encrypted = encryptionUtils.encrypt(
data = message,
key = secretKey
)
val decrypted = encryptionUtils.decrypt(encrypted)
println(decryptedPass.toString(), Charsets.UTF_8) // outputs "sample data"
}
Default security provider is set to Bouncy Castle.
Note
Changing provider has to be done before using any of the library functions/methods.
Example of changing provider for kipher-symmetric
:
import io.github.jhdcruz.kipher.symmetric.SymmetricEncryption
import java.security.Provider
import java.security.Security
fun main() {
// must be declared before using any symmetric ciphers methods!
val provider: Provider = Security.getProvider("SunJCE")
SymmetricEncryption.provider(provider)
}
import io.github.jhdcruz.kipher.symmetric.SymmetricEncryption;
import java.security.Provider;
import java.security.Security;
// For other JVM-based languages,
// adjust syntax based on language
class Main {
public static void main(String[] args) {
// must be declared only once before using any AES methods
// or at the beginning of the app's main method or such.
Provider provider = Security.getProvider("SunJCE");
SymmetricEncryption.Companion.setProvider(provider);
// and so on, so forth
}
}
If desired, it is also possible to change provider that affects the entire library modules.
import io.github.jhdcruz.kipher.aes.GcmEncryption
import io.github.jhdcruz.kipher.core.KipherProvider
import java.security.Provider
import java.security.Security
fun main() {
// must be declared only once before using any library functions
// or at the beginning of the app's main method or such.
val provider: Provider = Security.getProvider("SunJCE")
KipherProvider.provider = provider
val encryptionUtils = GcmEncryption()
// and so on, so forth
}
import io.github.jhdcruz.kipher.aes.GcmEncryption;
import io.github.jhdcruz.kipher.core.KipherProvider;
import java.security.Provider;
import java.security.Security;
// For other JVM-based languages,
// adjust syntax based on language
class Main {
public static void main(String[] args) {
// must be declared only once before using any AES methods
// or at the beginning of the app's main method or such.
Provider provider = Security.getProvider("SunJCE");
KipherProvider.Companion.setProvider(provider);
GcmEncryption encryptionUtils = GcmEncryption();
// and so on, so forth
}
}
Warning
provider
value is tied to the class itself, keep in mind when using the library
functions/methods in parallel with different providers.
I strive for backward-compatibility as much as possible, but due to the nature of this library being a cryptographic library, even a very small change can introduce a breaking change incompatible with previous versions.
The library will follow semantic versioning where every breaking changes bumps the major version regardless of how small the change is, this way developers know that something will not work should they update.
Note
Each modules are independently versioned to avoid version bumps between unrelated module/s.
If you want to contribute to this project, feel free to open an issue or discussion before opening a pull request to avoid wasted efforts.
This project is licensed under the Apache 2.0 License
- see the LICENSE file for
details
Important
I (@jhdcruz) am not a security expert/professional.
This library is primarily made for convenience and ease-of-use, while providing as much security as possible out-of-the-box.
If you found a security issue, please report the security issue.