Skip to main content

A secure SHA-256 hash generator with encrypted storage.

Project description

Locksum – Secure Hash Generator & Encrypted Vault

Cross-platform CLI + GUI for repeatable SHA-256 hashes, protected by a Fernet-encrypted vault (AES-CBC + HMAC). 100 % offline. 95 % test-coverage. AES-GCM support is already available via the experimental LSV2 format (set LOCKSUM_VAULT_VERSION=LSV2).

CI Coverage


🎯 Why Locksum?

Developers and security engineers often need to compute deterministic SHA-256 hashes and store them temporarily – API secrets, firmware checksums, build artefacts, never plaintext in documents. Locksum provides:

  • One-file binaries (locksum) for macOS, Linux, Windows.
  • Themed GUI for quick copy/paste workflows (tkinter + ttkbootstrap).
  • Strong cryptography – Argon2-id pass-code hashing, PBKDF2 or scrypt ➜ Fernet vault (LSV1). AES-256-GCM is already implemented in the experimental LSV2 format.
  • Zero network traffic – all keys & data live in an isolated directory ($LOCKSUM_DATA_DIR).
  • Modern DevSecOps – Ruff, Mypy, Bandit, Gitleaks, pip-audit, SBOM, PyInstaller, GitHub Pages.

🚀 Quick-start

1 · Binary

curl -LO https://github.com/guheye/locksum/releases/latest/download/locksum-$(uname -s)-$(uname -m)
chmod +x locksum*
./locksum hash "hello world"

2 · Python package

python -m pip install locksum
echo "My$tr0ngP@ss" | locksum store "secret"

3 · GUI

python -m locksum.main   # or simply: locksum

🔑 Cryptography Cheat-sheet

Purpose Primitive Notes
Passcode hash Argon2-id (64 MiB, t=2, p=4) Auto-rehash on policy change
Key derivation (KDF) PBKDF2-HMAC-SHA-256 / scrypt Chosen automatically from vault header
Encryption Fernet (AES-CBC + HMAC) LSV1 LSV2 (AES-256-GCM, AEAD – experimental)
Integrity HMAC-SHA-256 (LSV1) Built-in GCM tag (LSV2, experimental)
Memory hygiene secure_erase() ctypes memset Wipes bytearrays once used

Read the full vault-format spec for header layout & test vectors.


💻 CLI Usage

# Stateless hash
a=$(locksum hash "hello world")

# Hash *and* store in encrypted vault (pass-code piped via stdin)
echo "${PASS}" | locksum store "config.ini"

# List stored pairs (text: sha256)
echo "${PASS}" | locksum list

# Export vault ➜ .lsv file
echo "${PASS}" | locksum export backup.lsv

# Import vault (append)
echo "${PASS}" | locksum import backup.lsv

# **Irreversible** wipe of every artefact
echo "wipe all data" | locksum wipe --confirm "wipe all data"

Notes:

  • Pass-code is read from $LOCKSUM_PASSPHRASE_FD, piped stdin or an interactive prompt – never a flag.
  • Override the storage directory with $LOCKSUM_DATA_DIR.

🏗️ Architecture

graph TD;
  subgraph "GUI"
    A["View (tkinter)"] --> B["Controller"]
  end
  subgraph "Core"
    B --> C["CryptoModel"]
    C --> KM["KeyManager"]
    C --> VS["VaultStore"]
    C --> IC["IntegrityChecker"]
  end
  KM -->|"derive_key"| F(("Fernet Key"))
  VS -->|"encrypt/decrypt"| F
  IC -->|"HMAC"| VS
  • KeyManager – Argon2-id hasher + KDF wrappers, owns the Fernet / AES key.
  • VaultStore – persists ciphertext, reads/writes header, handles export & import.
  • IntegrityChecker – computes/verifies HMAC for LSV1 vaults. Authenticity for LSV2 vaults is provided by AES-GCM itself.

All three are dependency-injected for unit isolation (<100 LOC each).


🛡 Security & Threat-model (TL;DR)

  • Offline attacker with full disk access can't recover plaintext without pass-code (Argon2-id + Fernet).
  • Tampering flips the HMAC ➜ vault refuses to decrypt.
  • Side-channels (timing, cache) out of scope; future secretbox migration planned.

Full analysis in docs/threat_model.md.


🧪 Testing & CI

  • Unit tests (>95 % coverage) run on 3.11 & 3.12.
  • Property tests (Hypothesis) fuzz random passcodes/KDFs.
  • GUI smoke-test ensures widgets wire correctly on headless Xvfb.
  • DevSecOps – Ruff lint, Black format, Mypy types, Bandit static-analysis, Gitleaks secret scan, pip-audit SCA, CycloneDX SBOM.

📦 Releases

  • GitHub Actions draft GitHub/PyPI releases on tag v*.
  • PyInstaller one-file binaries uploaded as artefacts and release assets.
  • SBOM + SLSA provenance attached for supply-chain compliance.

🐳 (Opt-in) Docker

A pre-built image is published on GHCR:

docker run --rm ghcr.io/guheye/locksum:latest locksum --help

No Dockerfile is included in the repo to avoid image noise – it's generated in the release pipeline.


🔧 Development

git clone https://github.com/guheye/locksum && cd locksum
python -m pip install .[dev]
pre-commit install
pytest -q

Contributing

PRs welcome – please run make preflight (or the above steps) before opening a ticket.


📄 License

MIT © 2025 Michael Douglas / Contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

locksum-1.0.0.tar.gz (34.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

locksum-1.0.0-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file locksum-1.0.0.tar.gz.

File metadata

  • Download URL: locksum-1.0.0.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.13

File hashes

Hashes for locksum-1.0.0.tar.gz
Algorithm Hash digest
SHA256 37163948650d5b64315e04e635d263d1908b01f41bb5ef3b1cfaf782440e7b14
MD5 94634793eeba1f9188bad5f72154db97
BLAKE2b-256 f2ed01308fe09457fd5a7a3930cccbfcc3815a52d5f02ebe7b742eb52ecc47e2

See more details on using hashes here.

File details

Details for the file locksum-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: locksum-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 29.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.13

File hashes

Hashes for locksum-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 799194750b69f67601fcb7037b8f66c64341125f9f5c948880097c232aef9b89
MD5 a74b9795e0983765535af8ff5b205c14
BLAKE2b-256 36415ebb08bf3f2ca8dca793c6a5e5d171e55ff91238837fa18eb6c195242892

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page