Lightweight X.509 certificate toolkit for Kotlin/JVM. Build self-signed certs, CSRs, and work with PEM/DER encoding using JDK standard libs.
- Self-signed certificates β X.509v3 with SAN, Basic Constraints, key identifiers (EC keys)
- CSR creation β PKCS#10 Certificate Signing Requests with auto-discovered signature algorithms
- PEM read/write β load and encode certificates, private keys, public keys
- Private key formats β PKCS#8 unencrypted, PKCS#8 PBE-encrypted, PKCS#1 (RSA, DSA, EC)
- KeyStore loading β build JKS key/trust stores from PEM files
- TLS scanning β connect to any host and capture the certificate chain
- Trust store discovery β JDK cacerts, macOS Keychain, Windows-ROOT
- No BouncyCastle, no Guava β all crypto is pure JDK
java.security.*andjavax.crypto.*
- Private keys β PKCS#8, PKCS#8 encrypted, PKCS#1 (RSA, DSA, EC)
- Public keys β X.509/SPKI, PKCS#1 RSA
- Certificates β X.509v3 (PEM & DER)
- Key algorithms β RSA, EC (secp256r1, secp384r1, β¦), DSA
- Cert builder β EC keys (SHA256withECDSA)
Add the dependency:
dependencies {
implementation("dev.suresh.certkit:certkit:1.0.0-SNAPSHOT")
}val keyPair = KeyPairGenerator.getInstance("EC")
.apply { initialize(ECGenParameterSpec("secp256r1")) }
.generateKeyPair()
val cert = Cert.buildSelfSigned(
keyPair = keyPair,
serialNumber = 1,
issuer = X500Principal("CN=My CA,O=Acme"),
subject = X500Principal("CN=My CA,O=Acme"),
notBefore = LocalDate(2025, 1, 1),
notAfter = LocalDate(2026, 12, 31),
sanDnsNames = listOf("localhost", "*.local"),
sanIpAddresses = listOf(InetAddress.getLoopbackAddress()),
)
println(cert.pem)val keyPair = KeyPairGenerator.getInstance("RSA")
.apply { initialize(2048) }
.generateKeyPair()
val csr = Csr.create("CN=app.example.com,O=Acme", "SHA256withRSA", keyPair)
println(csr.pem)val privateKey = Pem.loadPrivateKey(Path("server.key"), keyPassword = "secret")
val publicKey = Pem.loadPublicKey(Path("server.pub"))
val certs = Pem.readCertificateChain(Path("chain.crt"))
val keyStore = Pem.loadKeyStore(Path("server.crt"), Path("server.key"))
val trustStore = Pem.loadTrustStore(Path("ca.crt"))val chain = scanCertificates("github.com")
chain.forEach { println("${it.commonName} β expires ${it.expiryDateUTC}") }println(keyPair.public.pem) // -----BEGIN PUBLIC KEY-----
println(keyPair.private.pem) // -----BEGIN PRIVATE KEY-----
println(certificate.pem) // -----BEGIN CERTIFICATE-----./amper build # Build
./amper test # Test
./amper publish mavenLocal # Publish to local Maven repositoryHuge thanks to the Airlift team. The crypto and DER/PEM logic in this library is a Kotlin rewrite of the security module, stripped of the Guava dependency and rewritten as idiomatic Kotlin.
Apache 2.0 β see LICENSE for details.
