jks
Java KeyStore (JKS) and PKCS12 encoder/decoder for Rust. Supports WebAssembly (WASM).
About
jks is a pure Rust library for reading and writing Java KeyStore (JKS) and PKCS12 files. It provides compatibility with Java's keytool and Android keystores, and can be used to:
- Read JKS files (keystores, truststores)
- Read PKCS12 files (Android
.keystore,.p12,.pfx) - Create new JKS files with private keys and certificates
- Extract private keys and certificates from keystores
- Convert keystores to PEM format and vice versa
Note: Private keys are assumed to be PKCS#8 encoded.
Features
- ✅ Read JKS files - Load existing Java keystores
- ✅ Read PKCS12 files - Load Android keystores,
.p12,.pfxfiles (pure Rust, no OpenSSL) - ✅ Auto-detect format - Automatically detects JKS vs PKCS12 format
- ✅ Write JKS files - Create new keystores compatible with Java
- ✅ Password-based encryption - Private keys encrypted using password (XOR + SHA-1)
- ✅ Private Key entries - Support for private keys with certificate chains
- ✅ Trusted Certificate entries - Support for trusted certificates
- ✅ Case-insensitive aliases - Alias matching is case-insensitive by default
- ✅ Ordered aliases - Optional alphabetical sorting of aliases
- ✅ Custom password validation - Configurable minimum password length
- ✅ WASM Support - Full JKS and PKCS12 support in WebAssembly
Installation
Add to your Cargo.toml:
[]
= "0.3.3"
Features
- default - Includes
randandpkcs12(PKCS12 support) - rand - Enable random number generation for JKS encryption
- pkcs12 - Enable PKCS12 support (for Android keystores) - uses pure Rust
p12-keystore - wasm - Build for WebAssembly (enables
getrandom/jsfor WASM environments)
To disable PKCS12 support (reduce dependencies):
[]
= { = "0.3", = false, = ["rand"] }
For WASM builds:
[]
= { = "0.3", = false, = ["pkcs12"] }
= { = "0.3", = ["wasm_js"] }
Quick Start
Reading a Keystore
use KeyStore;
use File;
Creating a New Keystore
use ;
use File;
use SystemTime;
API Reference
KeyStore
Main struct for working with Java keystores.
Creating a Keystore
use KeyStore;
// Default options
let ks = new;
// With custom options
let ks = with_options;
Loading & Saving
use KeyStore;
use File;
let mut ks = new;
// Load from file (JKS format)
let mut file = open?;
ks.load?;
// Auto-detect format (JKS or PKCS12)
let mut file = open?;
ks.load_auto_detect?;
// Load PKCS12 file (Android .keystore, .p12, .pfx)
let mut file = open?;
ks.load_pkcs12?;
// Save to file
let mut file = create?;
ks.store?;
PKCS12 Support (Android Keystores)
use KeyStore;
use File;
let mut ks = new;
// Load Android keystore (PKCS12 format)
let mut file = open?;
ks.load_pkcs12?;
// Or use auto-detect (works for both JKS and PKCS12)
let mut file = open?;
ks.load_auto_detect?;
// Get private key entry (already decrypted for PKCS12)
let alias = ks.aliases.first.unwrap.clone;
if ks.is_private_key_entry
Note: PKCS12 files (like Android keystores) are supported via the pure Rust p12-keystore library. The private keys from PKCS12 are already decrypted, so use get_raw_private_key_entry() instead of get_private_key_entry().
Private Key Entries
use ;
let mut ks = new;
// Add a private key entry
let entry = PrivateKeyEntry ;
// Private key will be encrypted before storing
ks.set_private_key_entry?;
// Retrieve and decrypt
let entry = ks.get_private_key_entry?;
// Get certificate chain only
let chain = ks.get_private_key_entry_certificate_chain?;
// Check if entry exists
if ks.is_private_key_entry
Trusted Certificate Entries
use ;
let mut ks = new;
// Add a trusted certificate
let entry = TrustedCertificateEntry ;
ks.set_trusted_certificate_entry?;
// Retrieve
let entry = ks.get_trusted_certificate_entry?;
// Check if entry exists
if ks.is_trusted_certificate_entry
Working with Aliases
use KeyStore;
let ks = new;
// Get all aliases
let aliases = ks.aliases;
// Check number of entries
let count = ks.len;
let empty = ks.is_empty;
// Delete an entry
ks.delete_entry;
// Case sensitivity
let ks = with_options;
Types
PrivateKeyEntry
Represents a private key with its certificate chain.
TrustedCertificateEntry
Represents a trusted certificate without a private key.
Certificate
Represents a single certificate.
KeyStoreOptions
Configuration options for keystore behavior.
Error Handling
All operations return Result<T, KeyStoreError>:
Examples
The library includes several examples demonstrating common usage:
1. PEM to JKS
Convert PEM files to a JKS keystore:
2. Read Keystore
Read and display entries from a keystore:
3. Read Truststore
Read Java's cacerts truststore:
4. JKS to PEM
Convert a JKS keystore to separate PEM files:
# Convert to separate PEM files
# Output files:
# output_private_key.pem - Private key (PKCS#8)
# output_certificate.pem - End-entity certificate
# output_chain.pem - Full certificate chain
5. JKS to PEM Bundle
Convert a JKS keystore to a single combined PEM bundle:
# Convert to single bundle file
# Bundle contains:
# -----BEGIN PRIVATE KEY-----
# -----END PRIVATE KEY-----
# -----BEGIN CERTIFICATE-----
# -----END CERTIFICATE-----
6. Compare Keystores
Test deterministic keystore output:
Password Security
Important: Always zero out passwords after use:
let mut password = b"mysecret".to_vec;
// Use password...
ks.store?;
// Zero out sensitive data
zeroing;
JKS Format Details
This library implements the JKS (Java KeyStore) format:
| Component | Value |
|---|---|
| Magic Number | 0xfeedfeed |
| Version | 2 (latest) |
| Digest Algorithm | SHA-1 |
| Key Encryption | Password-based XOR + SHA-1 |
| Salt Length | 20 bytes |
| Byte Order | Big-endian |
Private Key Encryption
Private keys are encrypted using:
- Generate 20-byte random salt
- Derive encryption key using SHA-1(password + salt) iterated
- XOR private key with derived key
- Append SHA-1 digest for verification
Entry Tags
| Tag | Type | Description |
|---|---|---|
| 1 | Private Key | Private key with certificate chain |
| 2 | Trusted Certificate | Trusted certificate without private key |
Testing
Run the test suite:
# Run all tests
# Run library tests
# Run specific example
WebAssembly (WASM) Support
This library fully supports WebAssembly for use in browser environments or Node.js. Both JKS and PKCS12 formats are supported in WASM.
Building for WASM
Using wasm-pack (recommended):
# Install wasm-pack
# Build for Node.js
# Build for web browsers
Or using cargo directly:
# Build the library for WASM
Using in Your Project
Add to your Cargo.toml:
[]
= { = "0.3", = false, = ["pkcs12"] }
= "0.2"
= { = "0.3", = ["wasm_js"] }
Providing a Custom RNG for WASM
For JKS write operations, you need to provide a custom RNG since the default RNG isn't available in WASM:
use ;
use ;
;
WASM Runtime Testing
The library has been verified working in WebAssembly runtime environment:
# Build the WASM test module
# Run tests with Node.js
Test Results (verified):
- ✅ Basic operations - PASSED
- ✅ Load JKS file - PASSED
- ✅ Load PKCS12 (.keystore) file - PASSED
- ✅ Get PKCS12 private key info - PASSED
- ✅ Auto-detect JKS format - PASSED
- ✅ Auto-detect PKCS12 format - PASSED
- ✅ Get JKS private key info (with decryption) - PASSED
All 7 tests PASSED for both JKS and PKCS12 in WASM!
Compatibility
- ✅ Java KeyStore (JKS) format
- ✅ PKCS12 format (.p12, .pfx, .keystore)
- ✅ Java
keytoolgenerated keystores - ✅ Android keystores
- ✅ Java cacerts truststore
- ✅ OpenSSL generated certificates
- ✅ PKCS#8 private keys
- ✅ WebAssembly (WASM)
Requirements
- Rust 1.70 or later
- No external C dependencies - Pure Rust implementation
License
MIT License - see LICENSE for details.
Acknowledgments
This library is a Rust port of the excellent Go implementation:
keystore-go by Pavlo Chernykh
PKCS12 support is powered by p12-keystore by Dmitry Pankratov.
Author
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.