A secure AES-GCM encryption utility with user-friendly features
Project description
secure-string-cipher
A security-focused AES-256-GCM encryption CLI tool with passphrase vault and modern cryptographic defaults.
Features
- AES-256-GCM encryption for text and files with authenticated encryption
- Argon2id key derivation – memory-hard, GPU/ASIC resistant
- Key commitment scheme – prevents partitioning oracle attacks
- Hidden password input – passwords hidden in interactive terminals, visible for scripts/tests
- Inline passphrase generation – type
/genat any password prompt - Encrypted passphrase vault with HMAC-SHA256 integrity verification
- Secure memory handling via libsodium (PyNaCl) when available
- Timing-safe operations – constant-time comparisons prevent side-channel attacks
- Chunked file streaming (64KB) for low memory usage
- Automatic vault backups (last 5 kept)
Quick Start
# Install
pip install secure-string-cipher
# Run interactive CLI
cipher-start
Installation
# Recommended: install with pipx
pipx install secure-string-cipher
# Or with pip
pip install secure-string-cipher
# Or from source
git clone https://github.com/TheRedTower/secure-string-cipher.git
cd secure-string-cipher
pip install .
Requires Python 3.12+
Usage
Run the interactive CLI:
cipher-start
You'll see this menu:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ AVAILABLE OPERATIONS ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ ┃
┃ TEXT & FILE ENCRYPTION ┃
┃ ┃
┃ [1] Encrypt Text → Encrypt a message (base64 output) ┃
┃ [2] Decrypt Text → Decrypt an encrypted message ┃
┃ [3] Encrypt File → Encrypt a file (creates .enc) ┃
┃ [4] Decrypt File → Decrypt an encrypted file ┃
┃ ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ PASSPHRASE VAULT (Optional) ┃
┃ ┃
┃ [5] Generate Passphrase → Create secure random password ┃
┃ [6] Store in Vault → Save passphrase securely ┃
┃ [7] Retrieve from Vault → Get stored passphrase ┃
┃ [8] List Vault Entries → View all stored labels ┃
┃ [9] Manage Vault → Update or delete entries ┃
┃ ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
┃ [0] Exit → Quit application ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Choose an option and follow the prompts.
Quick Passphrase Generation
When prompted for a password during encryption, you can type /gen (or /generate or /g) to instantly generate a strong passphrase:
Enter passphrase: /gen
🔑 Auto-Generating Secure Passphrase...
✅ Generated Passphrase:
8w@!-@_#M)wF,Qn(ms.Uv+3z
Entropy: 155.0 bits
💾 Store this passphrase in vault? (y/n) [n]: y
Enter a label for this passphrase: backup-2025
Enter master password to encrypt vault: ••••••••••••
✅ Passphrase 'backup-2025' stored in vault!
✅ Using this passphrase for current operation...
Generated passphrases have 155+ bits of entropy and can be stored directly in the encrypted vault.
Passphrase Vault
The vault stores passphrases encrypted with your master password at ~/.secure-cipher/passphrase_vault.enc:
- Generate & store – Option 5 or
/genduring encryption - Manual storage – Option 6 for existing passphrases
- Retrieve/manage – Options 7-9 for lookup, listing, and deletion
All vault operations use HMAC integrity verification and maintain automatic backups.
Docker
Use the pre-built image (Python 3.14-alpine based):
# Pull and run
docker pull ghcr.io/theredtower/secure-string-cipher:latest
docker run --rm -it ghcr.io/theredtower/secure-string-cipher:latest
# Or with Docker Compose
git clone https://github.com/TheRedTower/secure-string-cipher.git
cd secure-string-cipher
docker compose up -d
docker compose exec cipher cipher-start
To encrypt files in your current directory:
docker run --rm -it \
-v "$PWD:/data" \
ghcr.io/theredtower/secure-string-cipher:latest
With persistent vault and backups:
docker run --rm -it \
-v "$PWD/data:/data" \
-v "$PWD/vault:/vault" \
-v "$PWD/backups:/backups" \
ghcr.io/theredtower/secure-string-cipher:latest
Image details: ~65MB Alpine-based, runs as non-root (UID 1000), network-isolated.
Programmatic API
Use secure-string-cipher as a library in your Python projects:
Text Encryption
from secure_string_cipher import encrypt_string, decrypt_string
# Encrypt a message
ciphertext = encrypt_string("Secret message", "MySecurePass123!")
print(ciphertext) # Base64-encoded string
# Decrypt it back
plaintext = decrypt_string(ciphertext, "MySecurePass123!")
print(plaintext) # "Secret message"
File Encryption
from secure_string_cipher import encrypt_file, decrypt_file
# Encrypt a file (creates file.txt.enc)
encrypt_file("document.pdf", "MySecurePass123!")
# Decrypt it (creates document.pdf from document.pdf.enc)
decrypt_file("document.pdf.enc", "MySecurePass123!")
Passphrase Generation
from secure_string_cipher import generate_passphrase
# Generate a 24-character passphrase (155+ bits entropy)
passphrase = generate_passphrase(length=24)
print(passphrase) # e.g., "8w@!-@_#M)wF,Qn(ms.Uv+3z"
# Calculate entropy
from secure_string_cipher import calculate_entropy
bits = calculate_entropy(passphrase)
print(f"Entropy: {bits:.1f} bits")
Vault Operations
from secure_string_cipher import PassphraseVault
# Create or open vault
vault = PassphraseVault()
# Store a passphrase
vault.store("my-server", "MySecurePass123!", master_password="VaultMaster456!") # pragma: allowlist secret
# Retrieve it
password = vault.retrieve("my-server", master_password="VaultMaster456!") # pragma: allowlist secret
# List all labels
labels = vault.list_labels()
# Delete an entry
vault.delete("my-server", master_password="VaultMaster456!") # pragma: allowlist secret
Security Utilities
from secure_string_cipher import (
check_password_strength,
constant_time_compare,
has_secure_memory,
)
# Validate password strength
is_strong, issues = check_password_strength("weak")
if not is_strong:
print(f"Password issues: {issues}")
# Constant-time comparison (prevents timing attacks)
if constant_time_compare(user_input, stored_hash):
print("Match!")
# Check if libsodium secure memory is available
if has_secure_memory():
print("Using libsodium for secure memory zeroing")
Security
| Component | Implementation | Details |
|---|---|---|
| Encryption | AES-256-GCM | Authenticated encryption, 128-bit tags |
| Key Derivation | Argon2id | 64MB memory, 3 iterations, parallelism 4 |
| Key Commitment | HMAC-SHA256 | Prevents partitioning oracle attacks |
| Vault Integrity | HMAC-SHA256 | Detects tampering before decryption |
| Memory Security | libsodium | sodium_memzero() via PyNaCl |
| Timing Safety | Constant-time | All password/hash comparisons |
Additional protections: Path traversal prevention, symlink attack detection, atomic writes, user-only file permissions (600), 12-character minimum password with complexity requirements.
Password input: When running interactively, passwords are hidden (using getpass). When stdin is piped or redirected (scripts, automation, tests), passwords are visible. This allows both secure interactive use and scriptable automation.
Python memory limitations: Even with libsodium, Python strings are immutable and GC may copy objects. Use has_secure_memory() to check libsodium availability.
Development
git clone https://github.com/TheRedTower/secure-string-cipher.git
cd secure-string-cipher
pip install -e ".[dev]"
make format # Auto-format with Ruff
make test-quick # Fast tests (~10s, 207 tests)
make ci # Full CI pipeline (lint + type check + 548 tests)
See DEVELOPER.md for detailed development workflow and CONTRIBUTING.md for contribution guidelines.
License
MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file secure_string_cipher-1.0.30.tar.gz.
File metadata
- Download URL: secure_string_cipher-1.0.30.tar.gz
- Upload date:
- Size: 147.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6908ef387665d15b9c70fc89d7d5c4ec05961f7d4f77c9e4d13afb7714632d8
|
|
| MD5 |
1e20eeefbeeea260e7e7ed71f852694b
|
|
| BLAKE2b-256 |
4dd5385aaf32ffcacaba4d71083f0ecee1893245a152b4e605c225950a3cbc36
|
Provenance
The following attestation bundles were made for secure_string_cipher-1.0.30.tar.gz:
Publisher:
release.yml on TheRedTower/secure-string-cipher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
secure_string_cipher-1.0.30.tar.gz -
Subject digest:
c6908ef387665d15b9c70fc89d7d5c4ec05961f7d4f77c9e4d13afb7714632d8 - Sigstore transparency entry: 742153444
- Sigstore integration time:
-
Permalink:
TheRedTower/secure-string-cipher@47cb6240fb3589d4c6e4df5e4c000c35a89687f3 -
Branch / Tag:
refs/tags/v1.0.30 - Owner: https://github.com/TheRedTower
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47cb6240fb3589d4c6e4df5e4c000c35a89687f3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file secure_string_cipher-1.0.30-py3-none-any.whl.
File metadata
- Download URL: secure_string_cipher-1.0.30-py3-none-any.whl
- Upload date:
- Size: 55.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fc61b58a18dd895bf84c35d983f4612dcc760548278545021934ef4a0914ef1
|
|
| MD5 |
dc2003d7961400056ba6475060c8a4a8
|
|
| BLAKE2b-256 |
a35c2d7b63f710b7c5390c655ae1460e879a5354f78777fbb93afc23afb34711
|
Provenance
The following attestation bundles were made for secure_string_cipher-1.0.30-py3-none-any.whl:
Publisher:
release.yml on TheRedTower/secure-string-cipher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
secure_string_cipher-1.0.30-py3-none-any.whl -
Subject digest:
1fc61b58a18dd895bf84c35d983f4612dcc760548278545021934ef4a0914ef1 - Sigstore transparency entry: 742153466
- Sigstore integration time:
-
Permalink:
TheRedTower/secure-string-cipher@47cb6240fb3589d4c6e4df5e4c000c35a89687f3 -
Branch / Tag:
refs/tags/v1.0.30 - Owner: https://github.com/TheRedTower
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47cb6240fb3589d4c6e4df5e4c000c35a89687f3 -
Trigger Event:
push
-
Statement type: