# SeedPGP v1.4.7 **Secure BIP39 mnemonic backup using PGP encryption and QR codes** A client-side web app for encrypting cryptocurrency seed phrases with OpenPGP and encoding them as QR-friendly Base45 frames. Designed for offline use on TailsOS with built-in security verification. **Live Demo (Testing Only):** --- ## ๐Ÿšฆ Quick Start โ€” Recommended TailsOS Workflow For **real funds** ($100+), follow this airgapped TailsOS workflow: ```bash # 1. Boot TailsOS (airgapped - no network!) # 2. Open Terminal and run: git clone https://github.com/kccleoc/seedpgp-web.git cd seedpgp-web # 3. Build and verify (single command) make full-build-tails # 4. Serve locally in Tor Browser make serve-local # โ†’ Open http://localhost:8000 in Tor Browser ``` **That's it.** The Makefile handles everything: build, CSP injection, integrity verification, and security auditing. --- ## ๐Ÿ’ก Security-First Usage Guide | Your Fund Size | Recommended Setup | Build Command | Time | |----------------|-------------------|---------------|------| | **Testing** (<$100) | Any computer, local mode | `make build-offline` | 5 min | | **Real Use** ($100โ€“$10K) | Clean computer, network disabled | `make build-offline` | 15 min | | **Serious** ($10Kโ€“$100K) | **TailsOS or Ubuntu Live (airgapped)** | `make full-build-tails` | 30 min | | **Vault** (>$100K) | TailsOS + hardware wallet + multisig | `make full-build-tails` | 1+ hour | **The more funds at stake, the more security precautions you take.** **Note:** TailsOS and Ubuntu Live USB provide equivalent security for offline seed operations. See Path 1 (TailsOS) and Path 3 (Ubuntu Live) below for detailed workflows. --- ## ๐Ÿ”ง Makefile Commands Reference ### Core Build Commands ```bash # Install dependencies make install # Build for Cloudflare Pages (production) make build # Build for offline local testing make build-offline # Build for TailsOS with embedded CSP + integrity checks make build-tails # Full TailsOS pipeline (recommended for real use) make full-build-tails ``` ### Testing & Verification ```bash # Verify TailsOS build integrity (CSP, checksums, paths) make verify-tails # Verify offline compatibility make verify-offline # Run security audit make audit # Run test suite make test ``` ### Local Servers ```bash # Serve with Python HTTP server make serve-local # Serve with Bun server make serve-bun # Development mode (hot reload) make dev ``` ### Utility ```bash # Clean build artifacts make clean # Show all available commands make help ``` --- ## ๐Ÿ›ก๏ธ Path 1: TailsOS Airgapped Setup (RECOMMENDED for $10K+) This is the **gold standard** for seed phrase management. Takes 30 minutes, provides maximum security. ### Why TailsOS? - **Amnesic**: Runs entirely in RAM, leaves no trace on disk - **Airgapped**: You physically disconnect from all networks - **Isolated**: Browser can't access persistent storage - **Audited**: Open-source OS trusted by journalists and activists ### Step 1: Prepare TailsOS USB ```bash # On your primary computer: # 1. Download Tails ISO # Visit: https://tails.net/install/ # Download latest version (verify signature!) # 2. Burn to USB stick # Use Balena Etcher or dd command # Minimum 8GB USB required # 3. Label this USB "TAILS SEED OPS" # Keep separate from daily-use USBs ``` ### Step 2: Boot TailsOS (Airgapped) ```bash # Physical security checklist: โ–ก Unplug Ethernet cable from computer โ–ก Disable WiFi in BIOS (if possible) โ–ก Put phone in airplane mode (away from desk) โ–ก Close curtains (prevent shoulder surfing) # Boot process: 1. Insert TailsOS USB 2. Reboot computer 3. Press F12/ESC/DEL to enter boot menu 4. Select USB drive 5. Choose "Start Tails" 6. โš ๏ธ DO NOT configure WiFi when prompted 7. Verify network icon shows "disconnected" ``` ### Step 3: Build SeedPGP on TailsOS ```bash # Open Terminal (Applications โ†’ System Tools โ†’ Terminal) # Install Bun (first time only) curl -fsSL https://bun.sh/install | bash source ~/.bashrc # Clone repository git clone https://github.com/kccleoc/seedpgp-web.git cd seedpgp-web # Install dependencies make install # Build with security hardening make full-build-tails ``` **Note:** All builds include a baseline CSP in index.html, but the `make full-build-tails` pipeline injects a stricter, WASM-compatible CSP tailored for TailsOS. **What `make full-build-tails` does:** 1. **Cleans** all previous build artifacts 2. **Builds** with relative paths for offline use 3. **Injects** CSP meta tag directly into HTML 4. **Creates** `dist-tails/` directory with: - Complete app bundle - `README.txt` with SHA-256 checksums - Security documentation 5. **Verifies** CSP enforcement, relative paths, integrity 6. **Audits** for network calls, external URLs, security issues ### Step 4: Verify Build Integrity The build process automatically verifies: ```bash โœ… CSP enforces connect-src 'none' (all network calls blocked) โœ… Relative paths detected (offline compatible) โœ… No suspicious external domains โ„น๏ธ fetch() references exist in bundle (from openpgp.js) โœ“ These are BLOCKED by CSP connect-src 'none' at runtime โœ… TailsOS build verification complete ``` **Security Note:** `fetch()` and `XMLHttpRequest` references exist in the bundle (from OpenPGP.js library code), but they are **completely blocked** by CSP `connect-src 'none'` at the browser level. The verification confirms CSP enforcement, not the absence of dead code. ### Step 5: Serve Locally in Tor Browser ```bash # Start local HTTP server make serve-local # Output: # ๐Ÿš€ Starting local server at http://localhost:8000 # Press Ctrl+C to stop ``` **Open Tor Browser** (pre-installed in TailsOS): 1. Launch Tor Browser from desktop 2. Navigate to: `http://localhost:8000` 3. App loads โ€” all processing happens locally 4. Verify "Network BLOCKED" indicator in app header ### Step 6: Use SeedPGP Securely Now proceed to "Using SeedPGP" section below. All entropy generation, encryption, and QR generation happens offline in your browser's memory. **When finished:** ```bash # Stop server (Ctrl+C in Terminal) # Shutdown TailsOS (Applications โ†’ Shutdown) # โœ… All data erased from RAM # โœ… No trace left on computer ``` --- ## ๐Ÿ  Path 2: Local Offline Setup (Acceptable for <$10K) For smaller amounts, you can run on a regular computer with network disabled. ```bash # Clone repository git clone https://github.com/kccleoc/seedpgp-web.git cd seedpgp-web # Install dependencies make install # Build for offline use make full-build-offline # Disconnect network NOW: # - Unplug Ethernet # - Disable WiFi # - Airplane mode ON # Serve locally make serve-local # Open browser: http://localhost:8000 ``` **Security vs TailsOS:** | Feature | Local Offline | TailsOS Airgapped | |---------|---------------|-------------------| | RAM-only execution | โŒ No | โœ… Yes | | Disk trace | โš ๏ธ Possible | โœ… None | | Extension isolation | โš ๏ธ Manual | โœ… Automatic | | Memory dump protection | โŒ Limited | โœ… Strong | | **Best for** | Testing, <$10K | $10K+, serious use | --- ## ๐Ÿง Path 3: Ubuntu Live USB (Alternative to TailsOS) **Ubuntu Live USB provides equivalent security to TailsOS** for offline seed operations. It's RAM-only, amnesic (data erased on shutdown), and may be more familiar if you're already comfortable with Ubuntu. ### When to Use Ubuntu Live USB - โœ… You're already familiar with Ubuntu/Linux workflows - โœ… You only need offline operations (no Tor required) - โœ… You want faster boot time (~1 min vs Tails ~2 min) - โœ… You might need to install additional tools during the session ### Security Properties | Feature | Ubuntu Live USB | TailsOS | |---------|-----------------|---------| | RAM-only execution | โœ… Yes | โœ… Yes | | Amnesic (data erased on poweroff) | โœ… Yes | โœ… Yes | | Network isolation | โš ๏ธ Manual disable | โœ… Automatic (Tor-only) | | Pre-installed crypto tools | โŒ Need Python | โœ… GPG, KeePassXC built-in | | Boot time | ~1 min | ~2 min | | Best for | Offline seed ops | Offline + Tor workflows | **For your use case (offline seed blending): Both are equivalent.** --- ### Step 1: Prepare Ubuntu Live USB **On your regular computer:** ```bash # Download Ubuntu Desktop LTS ISO wget https://releases.ubuntu.com/24.04/ubuntu-24.04-desktop-amd64.iso # Verify SHA256 checksum sha256sum ubuntu-24.04-desktop-amd64.iso # Compare against official checksum from ubuntu.com/download # Create bootable USB (Linux/Mac) sudo dd if=ubuntu-24.04-desktop-amd64.iso of=/dev/sdX bs=4M status=progress # โš ๏ธ Replace /dev/sdX with your USB device (check with 'lsblk') # Windows: Use Rufus or balenaEtcher instead ``` **Prepare SeedPGP on a separate USB drive:** ```bash # Clone and build on your trusted computer git clone https://github.com/kccleoc/seedpgp-web.git cd seedpgp-web make install make full-build-tails # Creates dist-tails/ with embedded CSP # Generate checksum file cd dist-tails sha256sum index.html > CHECKSUM.txt cd .. # Copy to second USB drive (label it "SEEDPGP-OFFLINE") cp -r dist-tails/ /media/your-usb/seedpgp-offline/ ``` **You now have:** 1. **USB #1:** Ubuntu Live bootable installer 2. **USB #2:** Pre-verified SeedPGP build with checksums --- ### Step 2: Boot Ubuntu Live (Network Disabled) **Physical security checklist:** ``` โ–ก Unplug Ethernet cable from computer โ–ก Remove SIM card (if using a laptop with cellular) โ–ก Put phone in airplane mode (away from desk) โ–ก Close curtains (prevent shoulder surfing) ``` **Boot process:** 1. Insert Ubuntu Live USB (#1) 2. Reboot computer and press **F12/F2/ESC** during startup 3. Select USB drive from boot menu 4. Choose **"Try Ubuntu"** (NOT "Install Ubuntu") 5. **IMMEDIATELY after desktop loads:** Click network icon โ†’ **Disable Wi-Fi** 6. Verify network status in terminal: ```bash ip link show # All interfaces should show 'state DOWN' except 'lo' (loopback) # Confirm no external routes ip route # Should ONLY show: 127.0.0.0/8 dev lo ``` --- ### Step 3: Verify Clean State ```bash # Open Terminal (Ctrl+Alt+T) # Check no mounted writable drives mount | grep -v "ro," # Should only show read-only mounts (iso9660, squashfs) # Check no swap space swapon --show # Should return nothing # Verify RAM usage free -h # Should show ~2-4GB used (OS running entirely in RAM) ``` --- ### Step 4: Load and Verify SeedPGP ```bash # Insert USB #2 (SEEDPGP-OFFLINE) # It will auto-mount to /media/ubuntu/SEEDPGP-OFFLINE or similar # Navigate to the build folder cd /media/ubuntu/*/seedpgp-offline/ # Or use: cd /media/ubuntu/SEEDPGP-OFFLINE/seedpgp-offline/ # Verify integrity before running sha256sum -c CHECKSUM.txt # Should output: index.html: OK # If verification fails โ†’ STOP! Do not proceed. # Re-build on your trusted computer and copy again. ``` --- ### Step 5: Serve Locally with Python **Important:** You cannot open `file://` URLs directly in modern browsers due to CORS restrictions. You must serve over HTTP on localhost. ```bash # Start Python HTTP server (Python 3 is pre-installed) python3 -m http.server 8000 & # The '&' runs it in background # You'll see: # Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... ``` **Security verification: Localhost is safe** Even though the server listens on `0.0.0.0:8000` (all interfaces), there are **no active network interfaces** to reach it from outside: ```bash # Verify localhost-only access sudo ss -tlnp | grep 8000 # Shows: LISTEN 0.0.0.0:8000 (looks exposed, but...) # Check which interfaces exist ip addr show # Should ONLY show 'lo' (loopback 127.0.0.1) with status UP # No eth0, wlan0, or other interfaces should be UP # Try accessing from "outside" (this should fail) curl http://192.168.1.100:8000 # Use any typical LAN IP # Should instantly fail: "Network unreachable" ``` **The key:** Even though Python binds to `0.0.0.0`, there are no physical network paths to reach it. Localhost is a kernel-internal loopback interface. --- ### Step 6: Open in Firefox ```bash # Launch Firefox with localhost URL firefox http://localhost:8000 & ``` **Verify the app loaded correctly:** 1. SeedPGP interface appears 2. Check browser console (F12) for CSP enforcement: - Should see no CSP violation errors - Network tab should show only localhost requests 3. Verify "Network BLOCKED" indicator in app header --- ### Step 7: Use SeedPGP Now proceed with your seed operations (see "Using SeedPGP: The Workflow" section below): - Generate entropy (dice rolls recommended) - Blend multiple hardware wallet seeds (if applicable) - Encrypt to PGP key or password - Export QR backup - **Write final seed to paper immediately** **โš ๏ธ CRITICAL:** Never save anything to disk. All data stays in RAM. --- ### Step 8: Shutdown and Verify Data Erasure ```bash # Stop the Python server (not strictly necessary, but good practice) killall python3 # Power off Ubuntu Live sudo poweroff # Physical verification: โ–ก Remove both USB drives โ–ก All RAM contents are erased (power loss = data loss) โ–ก No trace left on computer's hard drive ``` **What just happened:** - โœ… All seed operations occurred in RAM only - โœ… Python HTTP server never had external network access - โœ… SeedPGP never wrote to persistent storage - โœ… Shutdown wiped all RAM contents - โœ… Computer's hard drive was never touched (read-only boot) --- ### Optional: Advanced Hardening If you want to match TailsOS-level security: **1. Disable swap (already disabled by default, but verify):** ```bash sudo swapoff -a ``` **2. Clear clipboard before shutdown:** ```bash # If you copied anything sensitive echo "" | xclip -selection clipboard ``` **3. Wipe RAM on shutdown (paranoid mode):** ```bash # For protection against cold-boot attacks (freezing RAM with liquid nitrogen) sudo apt install secure-delete sudo sdmem -v # Takes ~2 min, overwrites RAM with random data ``` **Note:** For your threat model (protecting seeds from remote attackers, not physical access to frozen RAM), step 3 is unnecessary. --- ### Ubuntu Live vs TailsOS: Summary **Use Ubuntu Live USB if:** - You're already comfortable with Ubuntu - You only need offline seed operations - You want faster boot time - You value familiarity over maximum security **Use TailsOS if:** - You want zero-config maximum security - You might need Tor for other operations - You're handling $100K+ and want the most audited option - You want automatic MAC randomization and anti-forensics **For your use case (three-hardware-wallet blend on Ubuntu Live): โœ… Perfectly safe.** --- ## ๐Ÿ” Using SeedPGP: The Workflow ### Step 1: Generate Entropy (New Seed) SeedPGP offers multiple entropy sources you can combine: ```bash ๐ŸŽฒ Dice Rolls - Physical randomness (99 rolls recommended) ๐ŸŽฅ Camera Noise - Visual entropy from textured surfaces ๐ŸŽต Audio Input - Microphone randomness from ambient sound ``` **Recommended: Dice Rolls (Highest Trust)** 1. Click **"Create"** tab โ†’ **"Dice Rolls"** 2. Roll physical dice 99 times 3. Enter each result (1-6) 4. App shows entropy progress bar 5. Click **"Generate Seed"** 6. **Your 12 or 24-word mnemonic appears** **โš ๏ธ CRITICAL:** Write down seed phrase on paper RIGHT NOW. Don't trust digital storage. ### Step 2: Encrypt Your Seed **Option A: Password-Based Encryption (Simplest)** ```bash 1. Your seed phrase is visible in the textarea 2. Enter a strong password (25+ characters): Example: "Tr0pic!M0nkey$Orange#2024@Secret%Phrase" 3. Confirm password 4. Click "Generate QR Backup" 5. Screenshot or print the QR code ``` **Option B: PGP Key Encryption (Most Secure)** ```bash # Prerequisites: Have a PGP keypair (generate with GPG) gpg --full-generate-key # Follow prompts gpg --armor --export your-email@example.com > public.asc # In SeedPGP: 1. Click "PGP Key Input" 2. Paste your public key 3. App shows fingerprint โ†’ verify it matches 4. Click "Use This Key" 5. Click "Generate QR Backup" 6. Save QR code securely ``` ### Step 3: Test Recovery IMMEDIATELY **โš ๏ธ DO NOT SKIP THIS STEP** ```bash 1. Click "Restore" tab 2. Scan or upload your QR backup 3. Enter password OR provide private key 4. Verify decrypted seed matches original 5. If mismatch โ†’ โš ๏ธ DO NOT USE, redo backup ``` **Why test?** Better to find a corrupt backup now than during an emergency. ### Step 4: Store Backups Securely You now have: - โœ… **Paper seed** (12/24 words handwritten) - โœ… **Encrypted QR code** (digital backup) **Storage strategy:** | Item | Location | Redundancy | |------|----------|------------| | Paper seed | Safe deposit box | Primary copy | | Paper seed copy 2 | Home safe | Backup copy | | QR code | USB drive in safe | Digital recovery | | QR code copy 2 | Cloud storage (encrypted!) | Disaster recovery | | Password/PGP key | Password manager | Encrypted separately | **Geographic distribution:** Keep copies in different physical locations (home, office, bank vault). --- ## ๐Ÿงช Development & Testing ### Run Tests ```bash # All tests make test # Individual test suites bun test src/lib/bip39.test.ts bun test src/lib/seedpgp.test.ts bun test src/lib/krux.test.ts ``` ### Development Mode ```bash # Hot reload development server make dev # With network blocking enabled by default VITE_NETWORK_BLOCK=true make dev ``` ### Security Auditing ```bash # Full security audit make audit # Output includes: # - CSP configuration check # - Network API usage analysis # - Persistent storage detection # - eval()/Function() detection # - Defense-in-depth layer summary ``` --- ## ๐Ÿ—๏ธ Build Artifacts Explained ### `make build-tails` Output ``` dist-tails/ โ”œโ”€โ”€ index.html # CSP injected, relative paths โ”œโ”€โ”€ assets/ โ”‚ โ”œโ”€โ”€ index-*.js # Main bundle (minified) โ”‚ โ”œโ”€โ”€ index-*.css # Styles โ”‚ โ””โ”€โ”€ secp256k1.wasm # Crypto library โ””โ”€โ”€ README.txt # SHA-256 checksums + usage instructions ``` ### CSP Configuration (Embedded in HTML) ```html ``` **Key directive:** `connect-src 'none'` โ€” Browser refuses ALL network requests (fetch, XHR, WebSocket, etc.) --- ## ๐Ÿ›ก๏ธ Security Architecture ### Defense-in-Depth Layers | Layer | Mechanism | Bypassable? | Purpose | |-------|-----------|-------------|---------| | **1. CSP** | `connect-src 'none'` in HTML | โŒ No (browser enforced) | **PRIMARY DEFENSE** | | 2. Network Blocker | JS patches window.fetch/XHR | โœ… Yes (console bypass) | Defense-in-depth | | 3. Airgapped OS | TailsOS, no network drivers | โŒ No (physical isolation) | Ultimate isolation | | 4. Session Crypto | AES-256-GCM, non-exportable | โš ๏ธ Memory dumps | Protects cached data | | 5. Auto-Clear | 10s clipboard wipe | โœ… Yes (user can cancel) | Reduces exposure window | **Primary Security:** CSP + TailsOS = two independent layers that must BOTH fail for compromise. ### Threat Model **What SeedPGP Protects Against:** โœ… Browser extensions stealing seed โœ… Malicious websites accessing clipboard โœ… Network exfiltration attempts โœ… Accidental data leaks to localStorage โœ… Session replay attacks **What SeedPGP CANNOT Protect Against:** โŒ Compromised TailsOS ISO (verify signatures!) โŒ Hardware keyloggers โŒ Evil maid attacks (physical device tampering) โŒ Memory dumps from privileged malware โŒ Social engineering (phishing for password) **Mitigation:** Use TailsOS (verified ISO) + physical security + test recovery immediately. --- ## ๐Ÿ“– Technical Documentation - [MEMORY_STRATEGY.md](doc/MEMORY_STRATEGY.md) - Why JS can't zero memory, defense strategies - [RECOVERY_PLAYBOOK.md](doc/RECOVERY_PLAYBOOK.md) - Offline recovery procedures - [TAILS_OFFLINE_PLAYBOOK.md](doc/TAILS_OFFLINE_PLAYBOOK.md) - Complete TailsOS workflow - [SeedPGP-Web-Forensic-Security-Report.pdf](doc/) - Independent security audit --- ## ๐Ÿ†˜ Troubleshooting ### Build Issues ```bash # Permission denied during build sudo chmod +x Makefile make clean && make install # Bun not found curl -fsSL https://bun.sh/install | bash source ~/.bashrc # CSP not embedded make clean build-tails grep "Content-Security-Policy" dist-tails/index.html ``` ### TailsOS Issues ```bash # Can't access localhost:8000 # โ†’ Check firewall: sudo ufw allow 8000 # โ†’ Use 127.0.0.1:8000 instead # Bun installation fails # โ†’ TailsOS persistence required # โ†’ Use temporary session, re-install each boot # Camera/microphone not working # โ†’ TailsOS may block by default # โ†’ Use dice rolls instead (recommended anyway) ``` ### Recovery Issues ```bash # QR scan fails # โ†’ Ensure good lighting, steady camera # โ†’ Upload image file instead of scanning # Decryption fails # โ†’ Verify password exactly matches # โ†’ Check PGP key fingerprint # โ†’ QR may be damaged โ†’ test backup immediately after creation! ``` --- ## โš–๏ธ License & Disclaimer **MIT License** - See LICENSE file **โš ๏ธ CRITICAL DISCLAIMER:** ``` CRYPTOCURRENCY SECURITY IS YOUR RESPONSIBILITY. This software is provided "AS IS", without warranty of any kind. 1. TEST with small amounts ($1-10) before trusting with real funds 2. VERIFY recovery works immediately after creating backup 3. STORE multiple copies in geographically distributed locations 4. USE TailsOS for amounts > $10K 5. CONSULT professional security advice for amounts > $100K Your seed phrase = your funds. Lose the seed = lose the funds. The author is NOT responsible for: - Lost funds due to bugs, user error, or hardware failure - Compromised devices or insecure storage - Forgotten passwords or lost backups If you don't understand how this works, start with $10 and test thoroughly. ``` --- ## ๐Ÿ™ Credits & Security **Author:** kccleoc **Security Audit:** v1.4.7 (February 2026) - No exploits found **License:** MIT **Report Security Issues:** - Private disclosure via [GitHub Security Advisory](https://github.com/kccleoc/seedpgp-web/security) - For urgent issues: Encrypt with PGP key in repository **Dependencies Audited:** - OpenPGP.js v5.11+ - BIP39 reference implementation - jsQR for QR scanning - secp256k1 WASM module --- ## ๐Ÿš€ Quick Reference Card ```bash # === PRODUCTION WORKFLOW (TailsOS) === make full-build-tails # Build + verify + audit make serve-local # Serve on localhost:8000 # === DEVELOPMENT === make dev # Hot reload make test # Run tests make audit # Security audit # === VERIFICATION === make verify-tails # Check CSP, checksums, paths grep "connect-src" dist-tails/index.html # Manual CSP check # === CLEANUP === make clean # Remove all build artifacts ``` **Remember:** More funds = more security steps. Don't skip TailsOS for serious amounts.