SecPaste is a Python library and CLI tool for sharing encrypted content via public pastebin services with zero-knowledge architecture. Features: - Pluggable crypto backends (AES-256-GCM, ChaCha20-Poly1305, Kyber-768) - Pluggable pastebin providers (dpaste.com, extensible) - URL fragment key storage (key never sent to server) - Both CLI and library usage - Post-quantum cryptography support (experimental) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
228 lines
7.5 KiB
Markdown
228 lines
7.5 KiB
Markdown
# SecPaste
|
|
|
|
**Encrypted pastebin client with pluggable cryptography backends**
|
|
|
|
SecPaste is a Python library and CLI tool for sharing encrypted content via public pastebin services. All encryption happens client-side, and the encryption key stays in the URL fragment (after `#`) so it never reaches the server.
|
|
|
|
## Features
|
|
|
|
- **Zero-knowledge architecture**: Server only stores encrypted data
|
|
- **Pluggable crypto backends**: AES-256-GCM, ChaCha20-Poly1305, and experimental post-quantum (Kyber)
|
|
- **Pluggable pastebin providers**: Easy to add support for any pastebin service
|
|
- **Both CLI and library**: Use as a command-line tool or import in your code
|
|
- **URL fragment key storage**: Encryption key never sent to server (stays after `#`)
|
|
|
|
## Security Model
|
|
|
|
```
|
|
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
│ Client │ │ Pastebin │ │ Reader │
|
|
│ │ │ Server │ │ │
|
|
│ plaintext │ │ │ │ │
|
|
│ ↓ │ │ │ │ │
|
|
│ encrypt │ │ │ │ │
|
|
│ ↓ │────────▶│ [encrypted] │────────▶│ fetch │
|
|
│ ciphertext │ POST │ content │ GET │ ↓ │
|
|
│ │ │ │ │ decrypt │
|
|
│ key ───────────────────────────────────────────────▶ ↓ │
|
|
│ (URL #fragment, never sent to server) │ plaintext │
|
|
└─────────────┘ └──────────────┘ └─────────────┘
|
|
```
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Basic installation
|
|
pip install cryptography requests
|
|
|
|
# For post-quantum crypto support (optional)
|
|
pip install liboqs-python
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### CLI Usage
|
|
|
|
```bash
|
|
# Paste from stdin (default: AES-256-GCM)
|
|
echo "secret message" | python -m secpaste.cli paste
|
|
|
|
# Paste a file
|
|
python -m secpaste.cli paste -f secret.txt
|
|
|
|
# Paste with ChaCha20-Poly1305
|
|
python -m secpaste.cli paste -f data.json -c chacha20-poly1305
|
|
|
|
# Paste with custom expiry and syntax highlighting
|
|
python -m secpaste.cli paste -f script.py --expiry week --syntax python
|
|
|
|
# Fetch and decrypt
|
|
python -m secpaste.cli fetch "https://dpaste.com/ABC123#aes-256-gcm:key..."
|
|
|
|
# Save fetched content to file
|
|
python -m secpaste.cli fetch "https://dpaste.com/ABC123#key..." -o output.txt
|
|
|
|
# List available options
|
|
python -m secpaste.cli list
|
|
```
|
|
|
|
### Library Usage
|
|
|
|
```python
|
|
from secpaste.client import SecPasteClient
|
|
|
|
# Initialize client (default: AES-256-GCM + dpaste)
|
|
client = SecPasteClient()
|
|
|
|
# Paste content
|
|
url = client.paste("secret data", expiry="week")
|
|
print(f"Share this URL: {url}")
|
|
# Output: https://dpaste.com/ABC123#aes-256-gcm:key...
|
|
|
|
# Fetch and decrypt
|
|
content = client.fetch(url)
|
|
print(content) # "secret data"
|
|
|
|
# Use different cipher
|
|
client = SecPasteClient(cipher='chacha20-poly1305')
|
|
url = client.paste("encrypted with ChaCha20")
|
|
|
|
# Register custom cipher or provider
|
|
from secpaste.crypto.base import CipherBackend
|
|
class MyCipher(CipherBackend):
|
|
# ... implementation ...
|
|
pass
|
|
|
|
SecPasteClient.register_cipher('my-cipher', MyCipher)
|
|
```
|
|
|
|
## Available Ciphers
|
|
|
|
| Cipher | Description | Key Size | Quantum-Safe? |
|
|
|--------|-------------|----------|---------------|
|
|
| `aes-256-gcm` | AES-256-GCM (default) | 32 bytes (~43 chars) | Symmetric: Yes |
|
|
| `chacha20-poly1305` | ChaCha20-Poly1305 | 32 bytes (~43 chars) | Symmetric: Yes |
|
|
| `kyber768-aes256-gcm` | Kyber-768 + AES-256 (experimental) | ~1KB (~1400 chars) | Yes (PQC) |
|
|
|
|
**Note**: Symmetric encryption (AES, ChaCha20) with 256-bit keys is already considered quantum-resistant. Post-quantum crypto (Kyber) protects against quantum attacks on key exchange, but produces much larger keys.
|
|
|
|
## Post-Quantum Cryptography
|
|
|
|
The `kyber768-aes256-gcm` cipher uses NIST-standardized Kyber-768 for key encapsulation combined with AES-256-GCM for data encryption.
|
|
|
|
**Pros:**
|
|
- Future-proof against quantum computer attacks on key exchange
|
|
- NIST-standardized algorithm
|
|
- Educational/experimental
|
|
|
|
**Cons:**
|
|
- Much larger keys (~1KB vs 32 bytes)
|
|
- Browser URL length limits may apply (typically 2KB-8KB)
|
|
- Requires `liboqs-python` library
|
|
- Less mature ecosystem
|
|
|
|
**Usage:**
|
|
```python
|
|
# Requires: pip install liboqs-python
|
|
from secpaste.crypto.pqc import KyberAESCipher
|
|
|
|
client = SecPasteClient(cipher='kyber768-aes256-gcm')
|
|
url = client.paste("quantum-safe secret")
|
|
# Warning: URL will be ~1.5KB longer than standard ciphers
|
|
```
|
|
|
|
## Supported Pastebin Providers
|
|
|
|
| Provider | Base URL | Notes |
|
|
|----------|----------|-------|
|
|
| `dpaste` | https://dpaste.com | Default, supports custom expiry |
|
|
|
|
### Adding Custom Providers
|
|
|
|
```python
|
|
from secpaste.providers.base import PastebinProvider
|
|
import requests
|
|
|
|
class MyPastebinProvider(PastebinProvider):
|
|
def paste(self, content: bytes, **kwargs) -> str:
|
|
# Upload content, return URL
|
|
pass
|
|
|
|
def fetch(self, paste_id: str) -> bytes:
|
|
# Fetch content, return bytes
|
|
pass
|
|
|
|
def get_name(self) -> str:
|
|
return "mypaste"
|
|
|
|
def get_base_url(self) -> str:
|
|
return "https://mypaste.com"
|
|
|
|
# Register it
|
|
SecPasteClient.register_provider('mypaste', MyPastebinProvider)
|
|
|
|
# Use it
|
|
client = SecPasteClient(provider='mypaste')
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
secpaste/
|
|
├── crypto/
|
|
│ ├── base.py # Abstract cipher interface
|
|
│ ├── aes.py # AES-256-GCM implementation
|
|
│ ├── chacha.py # ChaCha20-Poly1305 implementation
|
|
│ └── pqc.py # Kyber + AES (post-quantum)
|
|
├── providers/
|
|
│ ├── base.py # Abstract provider interface
|
|
│ └── dpaste.py # dpaste.com implementation
|
|
├── client.py # Main SecPaste client API
|
|
└── cli.py # Command-line interface
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
- **Server trust**: The pastebin server cannot read your content (it's encrypted), but it can:
|
|
- See paste metadata (size, IP, timing)
|
|
- Deny service or delete pastes
|
|
- Serve malicious JavaScript (if viewing in browser)
|
|
|
|
- **URL security**: The encryption key is in the URL fragment (`#key`):
|
|
- Never logged in server access logs
|
|
- Not sent in HTTP Referer headers
|
|
- But visible in browser history and can be leaked via client-side tracking
|
|
|
|
- **Key size**: Larger keys (like Kyber) may hit browser URL length limits
|
|
|
|
- **No authentication**: Anyone with the URL can decrypt the content
|
|
|
|
## Dependencies
|
|
|
|
- **cryptography**: For AES-256-GCM and ChaCha20-Poly1305
|
|
- **requests**: For HTTP API calls
|
|
- **liboqs-python** (optional): For post-quantum Kyber support
|
|
|
|
## License
|
|
|
|
MIT License - feel free to use, modify, and distribute.
|
|
|
|
## Contributing
|
|
|
|
PRs welcome! Areas for contribution:
|
|
- Additional pastebin providers (pastebin.com, termbin, privatebin, etc.)
|
|
- Additional cipher backends
|
|
- Better error handling
|
|
- Tests
|
|
- Browser extension
|
|
|
|
## Similar Projects
|
|
|
|
- **PrivateBin**: Full web application with similar security model
|
|
- **Magic Wormhole**: Secure file transfer with PAKE
|
|
- **Age**: Modern file encryption tool
|
|
|
|
---
|
|
|
|
**Reminder**: Never paste truly sensitive data (passwords, private keys) to public pastebins, even encrypted. Use proper secret management tools for production credentials.
|