Skip to content
developerHarish2007Public

About

Zero-dependency Python security toolkit — encrypted vault, TOTP codes, and a secrets scanner with a redact-and-rotate remediation flow. Stdlib only, no third-party packages.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

CipherOps

  ____  _       _                ___
 / ___|(_)_ __ | |__   ___ _ __|/ _ \ _ __  ___
| |    | | '_ \| '_ \ / _ \ '__| | | | '_ \/ __|
| |___ | | |_) | | | |  __/ |  | |_| | |_) \__ \
 \____|_| .__/|_| |_|\___|_|   \___/| .__/|___/
        |_|                         |_|

Zero dependency. Python standard library only. Track E — Zero Dependency Hackathon 2026.

I built CipherOps for the Zero Dependency Hackathon 2026 because most security tools are a thin wrapper around five npm/PyPI packages. I wanted to see how far I could get composing the primitives the language already ships — hashlib, hmac, secrets, struct, base64 — without importing a single third-party library. The answer turned out to be: pretty far.

Track E Zero Dependencies Tests Single File +5 Reproducible Build +5 Package Killer +3 STDLIB Log +3


CipherOps terminal demo


What It Does

CipherOps is a unified security CLI with three integrated components sharing one crypto engine:

Component What it replaces stdlib used
Encrypted Vault cryptography, passlib, keyring hashlib, hmac, secrets, json
TOTP / 2FA Generator pyotp (~1.9M downloads/week) hmac, struct, base64, hashlib
Secrets Scanner detect-secrets, truffleHog re, math, pathlib, os

Quickstart

# Run the entire tool — one file, no install
python cipherops.py --help

# Run the full test suite (38 tests)
python -m unittest discover -s tests -p "test_*.py"

Demo: What Using It Looks Like

Initialize & Store Secrets

$ python cipherops.py init
Set master password for new vault: ········
Confirm master password: ········
[+] Encrypted vault successfully initialized at: ~/.cipherops_vault.bin

$ python cipherops.py add github_pat ghp_xxxxxxxxxxxxxxxxxxxx
Enter master password: ········
[+] Secret 'github_pat' successfully encrypted and stored.

$ python cipherops.py list
Enter master password: ········
Stored Secrets:
 - github_pat

$ python cipherops.py get github_pat
Enter master password: ········
ghp_xxxxxxxxxxxxxxxxxxxx

Generate a 2FA Code

$ python cipherops.py totp add github JBSWY3DPEHPK3PXP
Enter master password: ········
[+] TOTP seed for 'github' saved to vault.

$ python cipherops.py totp code github
Enter master password: ········
Current TOTP code for 'github': 492039

Scan for Leaked Credentials

$ python cipherops.py scan ./myproject

[*] Scanning './myproject' for exposed credentials...

=== CipherOps Secrets Scan Report ===
[!] DETECTED 2 POTENTIAL SECRET(S):

[HIGH] AWS Access Key ID at ./myproject/config.py:12
      Redacted Value: AKIA***REDACTED*** (Entropy: 3.68)

[MEDIUM] Generic API Key / Secret Token at ./myproject/.env.bak:3
      Redacted Value: sk_l***REDACTED*** (Entropy: 4.12)

==================================================
[!] REMEDIATION NOTICE:
    Committed credentials are COMPROMISED — revoke them at the provider first.
    CipherOps can store your NEW replacement credential in the vault.

Rotate & vault NEW replacement for 'AWS Access Key ID'? [y/N]: y
Vault Secret Name [aws_access_key_id]: aws_prod_key
Enter NEW replacement value for 'aws_prod_key': ········
[+] Saved replacement secret 'aws_prod_key' into vault!

Why not store the found secret? Because it's already in git history — storing a compromised credential doesn't undo the exposure. CipherOps flags it, tells you to revoke it, and only stores the new replacement after rotation.


CLI Reference

python cipherops.py init                          # Create new encrypted vault
python cipherops.py add   <NAME> <VALUE>          # Store a secret
python cipherops.py get   <NAME>                  # Retrieve a secret
python cipherops.py list                          # List all secret names (never values)

python cipherops.py totp add  <NAME> [SEED]       # Add TOTP seed (auto-generates if omitted)
python cipherops.py totp code <NAME>              # Print current 6-digit TOTP code

python cipherops.py scan <PATH>                   # Scan for leaked credentials
python cipherops.py scan <PATH> --no-interactive  # Scan only, skip remediation prompts

# Options available on every command:
#   --vault PATH       Use a custom vault file instead of the default
#   --password TEXT    Pass master password inline (or set CIPHEROPS_PASSWORD env var)

Cryptographic Design

CipherOps does not invent a cipher. It composes five standard RFC primitives:

Master Password
      │
      ▼
hashlib.scrypt (N=16384, r=8, p=1)     ← CPU + memory-hard key stretching
      │
      ▼
  master_key (32 bytes)
      │
      ├─── HKDF-Extract + HKDF-Expand (RFC 5869) with info="cipherops-enc-v1"
      │         └──► key_enc (32 bytes)  ← Encrypts the payload
      │
      └─── HKDF-Extract + HKDF-Expand (RFC 5869) with info="cipherops-mac-v1"
                └──► key_mac (32 bytes)  ← Authenticates the entire file

Encryption:  HMAC-SHA256(key_enc, nonce + counter) XOR plaintext   ← CTR mode
Auth tag:    HMAC-SHA256(key_mac, header_bytes + ciphertext)        ← Encrypt-Then-MAC
Verification: hmac.compare_digest(tag, expected)  ← Constant-time, BEFORE decryption

Two subkeys are always derived — one for encryption, one for authentication — so the same key never does two jobs.

Threat Model

Protects against:

  • Ciphertext or header tampering — any bit flip anywhere raises ValueError, no garbage output
  • Malicious vault headers — scrypt parameters are bounds-checked before key derivation runs (prevents memory exhaustion attacks)
  • Timing side-channels — MAC comparison uses hmac.compare_digest throughout
  • Nonce reuse — all nonces are secrets.token_bytes(16) (CSPRNG)

Does not protect against:

  • Keyloggers or OS-level memory access capturing the master password at entry time
  • Weak master passwords — the strength of scrypt is bounded by the password you choose

Performance (measured on this machine)

Operation Time
Vault init (scrypt N=16384, r=8, p=1) ~37 ms
Secret add + get round-trip ~124 ms
Directory scan (50 files) ~30–370 ms

The scrypt cost parameters N, r, p are tunable. Increasing N makes brute-force attacks harder; decreasing it makes operations faster. The defaults are a reasonable balance for a local developer tool.


TOTP Engine (RFC 6238)

The TOTP generator reimplements pyotp using nothing but hmac, struct, and base64:

1. Decode the Base32 secret key
2. Compute T = floor(unix_timestamp / 30)   ← 30-second window
3. HMAC-SHA1(secret_bytes, T as 8-byte big-endian) → 20-byte digest
4. Dynamic truncation: offset = digest[-1] & 0x0F
5. Extract 4 bytes at offset, mask the top bit → 31-bit integer
6. code = integer % 10^6   → zero-padded 6-digit string

Verified against the official RFC 6238 Appendix B test vectors (SHA-1 and SHA-256).


Secrets Scanner

The scanner combines two independent signals to reduce false positives:

  1. Pattern matching — regex patterns for AWS Access Keys, GitHub PATs, private key headers, Slack tokens, and JWTs.
  2. Shannon entropy scoring — H = -Σ p(c) log₂ p(c). A 40-character uniform string like aaaaaaaaaa scores ~0.0 bits. A real API key scores >4.5 bits.

Confidence tiers:

  • HIGH — signature pattern matched (e.g. AKIA...) OR entropy > 4.5 bits
  • MEDIUM — generic pattern + entropy 3.5–4.5 bits
  • LOW — pattern matched but low entropy (likely a placeholder or hash, not a live credential)

Zero-Dependency Proof

requirements.txt is empty. Running pip install -r requirements.txt installs 0 packages.

$ python -c "
import sys, cipherops
stdlib = sys.base_prefix
non_std = [m for m in sys.modules.values()
           if hasattr(m, '__file__') and m.__file__
           and not m.__file__.startswith(stdlib)
           and 'CipherOps' not in m.__file__]
print('Third-party modules loaded at runtime:', len(non_std))
"
Third-party modules loaded at runtime: 0

All standard library modules used: argparse, base64, collections, getpass, hashlib, hmac, json, math, os, pathlib, re, secrets, struct, sys, time, typing.


Bonus Points

Single File (+5)

The complete implementation lives in one readable file — cipherops.py — which can be read top to bottom and understood. The src/ directory is the pre-consolidation modular version, kept for readability. tests/test_parity.py proves both produce identical outputs.

Reproducible Build (+5)

A Python source file is deterministic by definition. Two SHA-256 runs produce the same hash:

Run 1 SHA-256: ca2200e0588153f7100cfc4ab888ea71a36a6f69446b5476746f7de02d98feee
Run 2 SHA-256: ca2200e0588153f7100cfc4ab888ea71a36a6f69446b5476746f7de02d98feee

Package Killer (+3)

Package Killed Weekly Downloads Replaced with
cryptography ~353M/week hashlib + hmac + secrets (RFC 5869 HKDF + CTR + Encrypt-Then-MAC)
passlib ~9.1M/week hashlib.scrypt
pyotp ~1.9M/week hmac + struct + base64 (RFC 6238)

STDLIB Log (+3)

See STDLIB.md for all 11 substitutions with rationales. (Source: pypistats.org, Aug 2026)


Repository Layout

cipherops.py        ← Single-file executable (canonical submission artifact)
src/
  crypto.py         ← RFC 5869 HKDF, scrypt, CTR mode, Encrypt-Then-MAC
  vault.py          ← Encrypted JSON secret store
  totp.py           ← RFC 6238 / RFC 4226 TOTP engine
  scanner.py        ← Secrets scanner with entropy scoring
  cli.py            ← argparse CLI surface
tests/
  test_crypto.py    ← RFC 5869 Test Case 1, tamper resistance, scrypt bounds
  test_vault.py     ← Persistence, wrong password, disk round-trips
  test_totp.py      ← RFC 6238 Appendix B test vectors (SHA-1 & SHA-256)
  test_scanner.py   ← Entropy tiering, redaction, binary file skipping
  test_cli.py       ← Full CLI lifecycle, ANSI color suppression
  test_parity.py    ← cipherops.py vs src/ byte-for-byte output match
  test_single_file.py ← Single-file artifact verification
README.md           ← This file
STDLIB.md           ← All stdlib-for-package substitutions
LICENSE             ← MIT
requirements.txt    ← Empty
deps-proof.txt      ← Runtime audit log
.zero-dep.toml      ← Track E, one-line pitch
Makefile            ← make test / make proof / make hash

Running Tests

python -m unittest discover -s tests -p "test_*.py"
# Ran 38 tests in ~2s — OK

Individual test files can be run directly:

python -m unittest tests.test_crypto    # RFC 5869 verification
python -m unittest tests.test_totp     # RFC 6238 vectors
python -m unittest tests.test_parity   # single-file / src parity

Honest Limitations

  • The cipher is a composed construction, not a formally verified AEAD like AES-GCM. It is resistant to the attacks listed above and correct under the standard assumptions for HMAC-based constructions, but it has not been audited by a cryptographer.
  • http.server is not used. This is a pure CLI tool.
  • The vault is a single encrypted file. There is no concurrency control — two processes writing simultaneously will corrupt it.
  • The scanner generates false positives at LOW confidence. This is intentional and documented.

License

MIT — Copyright 2026 developerHarish2007

About

Zero-dependency Python security toolkit — encrypted vault, TOTP codes, and a secrets scanner with a redact-and-rotate remediation flow. Stdlib only, no third-party packages.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages