Notes on software, projects, and education.
I am excited to announce Cryptare v1.3.2, the release that makes stored keys do what they were always meant to do!
Cryptare is a Go terminal tool for encrypting, decrypting, compressing, and extracting files and directories. It combines a scriptable command-line interface with an interactive terminal UI and a small local store for password-protected keys. Files are encrypted with AES-256-GCM, streamed in authenticated chunks, under a key derived from your password with Argon2id.
v1.0.0 shipped on September 14. Since then, six releases have reworked the file format, the password handling, and the release pipeline. v1.3.2 lets you encrypt with a key from the key store instead of a password, gives every key a single password, and ships each release with signed build provenance and a container image on GitHub Container Registry.
$ cryptare keys generate --password-file master.txt
Generated key: ab0430cd1abad9e0
$ cryptare keys list
KEY ID ALGORITHM CREATED
ab0430cd1abad9e0 AES-256-GCM 2026-10-05 10:25
$ cryptare encrypt report.pdf --key ab0430cd1abad9e0 --password-file master.txt
Encrypted: report.pdf → report.pdf.enc
$ cryptare decrypt report.pdf.enc
Enter master password for key ab0430cd1abad9e0:
Decrypted: report.pdf.enc → report.pdf
cryptare encrypt <path> --key <key-id> (or -k) encrypts a file or folder with a key from the key store instead of a password; the TUI has a matching “Stored key ID” fielddecrypt needs no extra flag: it reads the key’s ID from the file’s header, takes the key from the key store, and asks for its master passwordcryptare keys export) somewhere other than the key store. keys delete now says so before it asks you to confirmkeys export asks for the key’s master password, checks it against the key, and protects the export with itkeys import checks that the key inside the export opens before it stores it--export-password-file, at the prompt, or in the TUI’s second password fieldghcr.io/jabbott-iii/cryptare, tagged 1.3.2, 1.3, and latestlinux/amd64 with CGO, from base images pinned by digest10001) and keeps its key store in the /app/data volumechecksums.txt, and the container image carry a signed SLSA build provenance attestation from the release workflow, so you can check that a download was built from this repository’s tagged sourcemake check runs CI’s checks locally, in CI’s order; make check-all adds gosec, govulncheck, and the workflow lintergo run, so there is nothing extra to installIf you last looked at Cryptare in the v1.0.0 post, here is what changed along the way:
LICENSE, NOTICE, and THIRD_PARTY_LICENSES.txt--password-file keeps passwords out of your shell history, and passwords are Unicode-normalised (NFKC), so the same password matches however its characters were typed--force, outputs are written atomically, and Ctrl+C removes unfinished outputdecompress, and decrypt of an encrypted folder, stop at 10 GiB of output or 100,000 entries by default (--max-size, --max-entries), and on Linux and macOS extracted files are private to youcryptare keys path shows wherecompress --format zip), decompress --raw, --version, and vim-style TUI bindings (cryptare --vim)# Protect a document before copying it to a USB drive or cloud storage
cryptare encrypt ./tax-return.pdf
# Back up a project folder as one encrypted file, then restore it later
cryptare encrypt ./project-dir --output ./project-dir-backup.enc
cryptare decrypt ./project-dir-backup.enc --output ./restored-project-dir
# Encrypt with a stored key instead of choosing a password for each file
cryptare keys generate # prints "Generated key: <key-id>"
cryptare encrypt ./report.pdf --key 3f9a1c0e7b2d4a6f
cryptare keys export 3f9a1c0e7b2d4a6f --output /media/backup/3f9a1c0e7b2d4a6f.ckey
# In scripts, read the password from a file only you can read
cryptare encrypt ./secret.txt --password-file ~/.config/cryptare/pw.txt
# Package build output as a zip, and extract a large archive with a higher limit
cryptare compress ./build --format zip
cryptare decompress ./huge-dataset.tar.gz --max-size 50GiB
# Use menus instead of flags
cryptare --vim
Download the archive for your platform and checksums.txt from the v1.3.2 release:
| Platform | Archive |
|---|---|
| Linux (x86-64) | cryptare_linux_amd64.tar.gz |
| Linux (ARM64) | cryptare_linux_arm64.tar.gz |
| macOS (Apple Silicon) | cryptare_darwin_arm64.tar.gz |
| macOS (Intel) | cryptare_darwin_amd64.tar.gz |
| Windows (x86-64) | cryptare_windows_amd64.zip |
On Linux (use linux_arm64 in place of linux_amd64 on ARM64):
BASE=https://github.com/jabbott-iii/Cryptare/releases/download/v1.3.2
curl -LO "$BASE/cryptare_linux_amd64.tar.gz"
curl -LO "$BASE/checksums.txt"
sha256sum --ignore-missing -c checksums.txt
tar -xzf cryptare_linux_amd64.tar.gz
chmod +x cryptare_linux_amd64
sudo mv cryptare_linux_amd64 /usr/local/bin/cryptare
cryptare --version
On macOS, use the matching darwin archive the same way and check its hash with shasum -a 256. On Windows, extract the zip, rename cryptare_windows_amd64.exe to cryptare.exe, and add it to your PATH. There is no Windows ARM64 build.
docker pull ghcr.io/jabbott-iii/cryptare:1.3.2
docker run --rm -it -v cryptare-data:/app/data ghcr.io/jabbott-iii/cryptare:1.3.2
This opens the TUI with its key store in the cryptare-data volume. To use a folder on the host instead, run the container as your own user with --user "$(id -u):$(id -g)", as the README’s Docker section shows.
Building needs Go 1.26 or newer and a C compiler (gcc or clang) with CGO enabled, because the SQLite driver behind the key store uses CGO. On Windows, use a MinGW-w64 toolchain and run make from Git Bash.
git clone https://github.com/jabbott-iii/Cryptare.git
cd Cryptare
git checkout v1.3.2
make build
./bin/cryptare --version
checksums.txt shows that a download wasn’t damaged; the attestation shows where it came from. Verify an archive or the image with the GitHub CLI (after gh auth login):
gh attestation verify cryptare_linux_amd64.tar.gz --repo jabbott-iii/Cryptare \
--signer-workflow jabbott-iii/Cryptare/.github/workflows/cd.yml \
--source-ref refs/tags/v1.3.2
gh attestation verify oci://ghcr.io/jabbott-iii/cryptare:1.3.2 --repo jabbott-iii/Cryptare \
--signer-workflow jabbott-iii/Cryptare/.github/workflows/cd.yml \
--source-ref refs/tags/v1.3.2
Everything v1.3.1 wrote still opens in v1.3.2. A few behaviours changed:
keys export now takes the key’s master password rather than a separate export password. A script that passed a different export password fails with “wrong master password”, and a key whose master password is shorter than 15 characters can’t be exported; generate a new key instead.keys import checks the key inside the export. An older export with its own password needs both passwords (see above).encrypt --key, and decrypt of a file encrypted with a stored key, open the key store; the other file commands still never touch it.The full list, including notes for older versions, is in the README.
go.mod is tidy and that no key material is committed, runs go vet, golangci-lint, and the full test suite on Linux, macOS, and Windows (with the race detector on Linux and macOS), and smoke-tests the built binarychecksums.txt and signed build provenance for each archive and the container imageFound a bug or have an idea for a feature? Please open an issue. Contributions are welcome. See CONTRIBUTING.md, and confirm the idea on an issue before opening a pull request.
Thank you for following along!