Files
pyhdwallet/BestPractices.md
2026-01-08 00:12:37 +08:00

6.9 KiB

Offline Security Best Practices

This tool is designed for offline use, but true security depends on the environment where you run it. Below are operational security recommendations for generating keys you can trust.

Air-Gapped Setup (Highest Security)

For maximum security when generating production wallets, use an air-gapped computer—a device that has never been and will never be connected to any network.

Recommended procedure:

  1. Prepare a clean machine:

    • Use a dedicated laptop or bootable USB with a fresh Linux installation (e.g., Tails, Ubuntu Live USB)
    • Never connect this device to WiFi, Ethernet, or Bluetooth [web:14]
    • Physically disable network interfaces if possible (remove WiFi card, tape over Ethernet port)
  2. Transfer dependencies offline:

    # On an online machine, download dependencies
    pip download -r requirements.txt -d ./offline-deps
    
    # Transfer ./offline-deps to air-gapped machine via USB
    # On air-gapped machine:
    pip install --no-index --find-links=./offline-deps -r requirements.txt
    
  3. Verify code integrity:

    • Check the git commit hash matches the version you reviewed
    • Optionally run pytest -v tests/test_vectors.py on the air-gapped machine to verify derivation logic
  4. Generate wallet:

    python ./src/pyhdwallet.py gen --pgp-pubkey-file pubkeys/recipient.asc --file --off-screen
    
  5. Transfer output safely:

    • Copy only the .wallet/*.zip file to USB (never copy pyhdwallet.py or Python environment back to online machine)
    • The ZIP is AES-encrypted; the inner .asc is PGP-encrypted [web:19]
  6. Destroy or securely wipe the USB after transfer if it contained unencrypted secrets

Threats Air-Gapping Mitigates

  • Remote attacks: Malware cannot exfiltrate keys over the network
  • Clipboard hijacking: No clipboard manager or remote access tool can intercept data
  • Browser/OS telemetry: No accidental upload of terminal history or crash dumps

Threats Air-Gapping Does NOT Fully Mitigate

Research shows that sophisticated attackers with physical access can potentially exfiltrate data from air-gapped systems via covert channels (acoustic, electromagnetic, optical) [web:18]. However:

  • These attacks require physical proximity and pre-installed malware [web:18]
  • For individual users (not nation-state targets), air-gapping remains highly effective
  • Countermeasures: Use the machine in a secure location, inspect for unfamiliar USB devices, verify software integrity before installation [web:18]

Physical Security

Mnemonic handling:

  • Write the mnemonic on paper immediately; never store it digitally on the air-gapped machine
  • Use a metal backup (e.g., Cryptosteel) for fire/water resistance
  • Split storage across multiple secure locations if desired (Shamir's Secret Sharing for advanced users)

Device handling:

  • After generating the wallet, optionally wipe the air-gapped device or destroy the bootable USB
  • If reusing the device, use secure-erase tools (not just rm)

Verification Through Testing

Why the test suite matters for trust:

The committed test suite (tests/test_vectors.py) allows you to verify that derivation logic hasn't been tampered with before generating production keys:

# On the air-gapped machine, before generating your wallet:
pytest -v tests/test_vectors.py

If all tests pass, you have cryptographic proof that:

  • BIP39 seed derivation matches the well-known test vector ("abandon abandon..." → known seed) [file:2]
  • Derivation paths produce addresses matching public BIP39/BIP44 test vectors
  • PGP fingerprinting logic works correctly

If tests fail, do not generate keys—the code may be compromised or buggy.

Entropy Sources

Built-in entropy (default):

  • Python's secrets.token_bytes() uses OS-provided CSPRNG (/dev/urandom on Linux, CryptGenRandom on Windows)
  • This is cryptographically secure for typical use

Additional user entropy (optional):

python ./src/pyhdwallet.py gen --dice-rolls "4 2 6 1 3 5 ..." --file
  • Roll a die 50+ times and input the results
  • Your dice rolls are mixed with OS entropy via SHA256 [file:2]
  • Protects against potential CSPRNG backdoors (theoretical concern)

PGP Key Fingerprint Pinning

Always use --expected-fingerprint when encrypting to a PGP key to prevent key substitution attacks [file:2]:

# First, get and verify the fingerprint of your recipient key
python ./src/pyhdwallet.py fetchkey https://example.com/mykey.asc --out mykey.asc
# Manually verify fingerprint matches what you expect (check via another channel)

# Then use it with pinning:
python ./src/pyhdwallet.py gen \
  --pgp-pubkey-file mykey.asc \
  --expected-fingerprint A27B96F2B169B5491013D2DA892B822C14A9AA18 \
  --file

Without --expected-fingerprint, an attacker who controls the filesystem could swap mykey.asc with their own key.

Operational Checklist

Before generating production wallets:

  • Running on air-gapped machine or fresh Live USB
  • Network physically disabled (no WiFi/Ethernet/Bluetooth)
  • Code integrity verified (git commit hash + test suite passes)
  • Using --off-screen to minimize terminal scrollback exposure
  • Using --file to avoid leaving unencrypted files on disk
  • Using --pgp-pubkey-file with --expected-fingerprint for key pinning
  • Paper/metal backup prepared for mnemonic
  • Output ZIP password stored separately from ZIP file
  • Plan for USB secure wipe after transfer

Lower-Risk Scenarios

Air-gapping is overkill for:

  • Learning/testing: Use your regular laptop with --off-screen and --file
  • Small amounts: Generate on a clean, updated machine with minimal software
  • Testnet wallets: Standard laptop is fine

Air-gapping is recommended for:

  • Life savings or business funds
  • Long-term cold storage (multi-year hold)
  • Institutional custody scenarios

Trust But Verify

The only way to fully trust this tool (or any wallet software) is to:

  1. Read the source code (src/pyhdwallet.py is ~1400 lines, single file)
  2. Verify test vectors match published BIP39 test data
  3. Run the test suite on your air-gapped machine
  4. Generate a test wallet and verify addresses on a block explorer using a separate tool

Never trust wallet software blindly—especially for significant funds


Key additions:

  1. Air-gapped setup procedure with offline dependency installation
  2. Threat model (what air-gapping protects against and doesn't)
  3. Physical security best practices for mnemonic backup
  4. Test suite as verification tool before generating production keys
  5. Entropy sources explanation (dice rolls for paranoid users)
  6. PGP fingerprint pinning rationale
  7. Operational security checklist for production use
  8. Risk-based guidance (when air-gapping is overkill vs. essential)
  9. "Trust but verify" philosophy for crypto software