Hardware-encrypted folder compression powered by YubiKey. Lock your files with military-grade AES-256 encryption — only your YubiKey can unlock them. Touch to encrypt. Touch to decrypt. No passwords to remember, no keys to manage.
- Hardware-bound encryption — AES-256-GCM with keys wrapped by YubiKey RSA-2048
- Touch required — Physical touch on YubiKey for every operation
- PIN protected — YubiKey PIV PIN required for decryption
- Backup YubiKey — Optionally add a second YubiKey for redundancy
- Multi-threaded compression — Zstandard with configurable CPU threads (1-22 levels)
- Tamper-proof — AES-GCM AAD protects headers against modification
- Secure memory — All keys, PINs, and sensitive data zeroized after use
- Cross-platform — Windows, macOS, Linux
- Single binary — No runtime dependencies, ~7MB
Folder → tar → zstd compress → AES-256-GCM encrypt → .ubk file
│
Session key wrapped with
YubiKey RSA public key
(touch required)
A random session key is generated per file, encrypted with your YubiKey's RSA public key, and stored in the .ubk file. Decryption requires the matching YubiKey (private key never leaves hardware) + PIN + touch.
Windows
Rust:
- Download and run rustup-init.exe
- Follow the prompts (default options are fine)
- Restart your terminal
# Verify installation
rustc --version
cargo --versionYubiKey Manager:
- Download from yubico.com/support/download/yubikey-manager
- Run the installer
- Both GUI and CLI (
ykman) will be installed
# Verify ykman is accessible
& "C:\Program Files\Yubico\YubiKey Manager\ykman.exe" --versionSmart Card service: Built-in, no setup needed.
macOS
Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/envYubiKey Manager:
brew install ykmanOr download from yubico.com/support/download/yubikey-manager.
PC/SC: Built-in on macOS, no setup needed.
Linux (Ubuntu/Debian)
Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/envBuild dependencies:
sudo apt update
sudo apt install -y build-essential pkg-config libpcsclite-devYubiKey Manager:
sudo apt install -y yubikey-managerOr via pip:
pip install yubikey-managerSmart Card service:
sudo apt install -y pcscd
sudo systemctl enable --now pcscdLinux (Fedora/RHEL)
Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/envBuild dependencies:
sudo dnf install -y gcc pkg-config pcsc-lite-develYubiKey Manager:
sudo dnf install -y yubikey-managerSmart Card service:
sudo dnf install -y pcsc-lite
sudo systemctl enable --now pcscdLinux (Arch)
Rust:
sudo pacman -S rustup
rustup default stableBuild dependencies & tools:
sudo pacman -S base-devel pkg-config pcsclite ccid
sudo systemctl enable --now pcscdYubiKey Manager:
sudo pacman -S yubikey-managergit clone https://github.com/theleaks/UbiKeyZipper.git
cd UbiKeyZipper
cargo build --release| Platform | Binary location |
|---|---|
| Windows | target\release\ubikeyzipper.exe |
| macOS | target/release/ubikeyzipper |
| Linux | target/release/ubikeyzipper |
Insert your YubiKey and run the following commands once:
Windows (PowerShell)
# Generate RSA key with mandatory touch
& "C:\Program Files\Yubico\YubiKey Manager\ykman.exe" piv keys generate --algorithm RSA2048 --touch-policy ALWAYS 9d pubkey.pem
# Press Enter for default management key
# Create certificate (enter your PIN when prompted)
& "C:\Program Files\Yubico\YubiKey Manager\ykman.exe" piv certificates generate -s "UbiKeyZipper" 9d pubkey.pem
# Press Enter for default management key, then enter PIN, then touch YubiKey
# Change default PIN (strongly recommended)
& "C:\Program Files\Yubico\YubiKey Manager\ykman.exe" piv access change-pin
# Old PIN: 123456 → enter your new 6-8 digit PIN
# Clean up (key is inside YubiKey now)
Remove-Item pubkey.pemmacOS / Linux
# Generate RSA key with mandatory touch
ykman piv keys generate --algorithm RSA2048 --touch-policy ALWAYS 9d pubkey.pem
# Press Enter for default management key
# Create certificate (enter your PIN when prompted)
ykman piv certificates generate -s "UbiKeyZipper" 9d pubkey.pem
# Press Enter for default management key, then enter PIN, then touch YubiKey
# Change default PIN (strongly recommended)
ykman piv access change-pin
# Old PIN: 123456 → enter your new 6-8 digit PIN
# Clean up (key is inside YubiKey now)
rm pubkey.pemWhat happened? An RSA-2048 key pair was generated inside the YubiKey's secure chip. The private key never leaves the hardware.
pubkey.pemwas only needed during setup and can be deleted.
# Windows
.\target\release\ubikeyzipper.exe
# macOS / Linux
./target/release/ubikeyzipper- Click Select... and choose a folder
- Click Refresh to detect your YubiKey
- Select your YubiKey from the dropdown
- Adjust CPU Threads and Compression Level as needed
- Click Encrypt
- Choose where to save the
.ubkfile - Touch your YubiKey when the LED blinks
- Switch to the Decrypt tab
- Click Select .ubk... and choose your encrypted file
- Click Refresh and select your YubiKey
- Enter your PIN
- Select an Export folder
- Click Decrypt & Export
- Touch your YubiKey when the LED blinks
| Control | Range | Default | Description |
|---|---|---|---|
| CPU Threads | 1 — max cores | All cores | Number of parallel compression threads |
| Compression Level | 1 — 22 | 7 | 1-3: Fast / 4-10: Balanced / 11-22: Maximum |
Higher compression = smaller file, more time. More threads = faster compression, more CPU usage.
+----------------------------------+
│ Magic: "UBK\x01" (4B) │ Format + version
│ Key slot count (1B) │ 1 or 2 (with backup)
│ ── Key Slot ── │
│ Certificate fingerprint (32B) │ SHA-256 of YubiKey cert
│ Wrapped key length (4B) │ RSA ciphertext size
│ Wrapped AES key (var) │ RSA-encrypted session key
│ ── Encrypted Payload ── │
│ Nonce (12B) │ AES-GCM nonce
│ Ciphertext length (8B) │ Payload size
│ Ciphertext (var) │ Encrypted zstd-compressed tar
│ Auth tag (16B) │ AES-GCM integrity tag
+----------------------------------+
Header is authenticated via AES-GCM AAD — any tampering is detected.
| Property | Detail |
|---|---|
| Encryption | AES-256-GCM (authenticated) |
| Key wrapping | RSA-2048 via YubiKey PIV hardware |
| Key storage | Private key in YubiKey chip, non-exportable |
| Access control | PIN (6-8 digits) + physical touch |
| Memory | Keys, PINs, plaintext zeroized after use |
| Integrity | AES-GCM AAD over full header |
| RNG | OS CSPRNG (OsRng) |
See SECURITY.md for the full threat model.
YubiKey lost? → Files encrypted with it are permanently inaccessible. Use backup YubiKey option.
.ubk file lost? → Only the encrypted copy is lost. Originals are unaffected.
.ubk tampered? → Decryption fails with authentication error.
PIN forgotten? → YubiKey PIV can be factory reset, but all keys are destroyed.
src/
├── main.rs Entry point
├── app.rs App state, egui routing
├── worker.rs Background encrypt/decrypt thread
├── ui/
│ ├── theme.rs Dark theme
│ ├── encrypt_tab.rs Encrypt UI
│ ├── decrypt_tab.rs Decrypt UI
│ └── widgets.rs Progress bar, buttons, YubiKey prompt
├── core/
│ ├── archiver.rs Folder ↔ tar
│ ├── compression.rs zstd multi-threaded compress/decompress
│ ├── encryption.rs AES-256-GCM + AAD
│ └── pipeline.rs Full encrypt/decrypt orchestration
├── yubikey/
│ ├── detect.rs YubiKey scanning
│ └── piv.rs PIV cert read, key wrap/unwrap
└── format/
└── ubk.rs .ubk binary format
cargo test # 21 tests
cargo clippy -- -D warnings # Lint
cargo build --release # Optimized buildPre-built binaries for every release are available on the Releases page:
| Platform | File |
|---|---|
| Windows x86_64 | ubikeyzipper-windows-x86_64.zip |
| macOS x86_64 (Intel) | ubikeyzipper-macos-x86_64.tar.gz |
| macOS aarch64 (Apple Silicon) | ubikeyzipper-macos-aarch64.tar.gz |
| Linux x86_64 | ubikeyzipper-linux-x86_64.tar.gz |
SHA-256 checksums are included with each release.
- Branch → implement →
cargo test+cargo clippy -- -D warnings→ PR
egui · yubikey.rs · RustCrypto · zstd-rs