Skip to content

security: encrypt EOA private key with keystore JSON#34

Open
hadv wants to merge 3 commits intomasterfrom
hadv/eoa-keystore-output
Open

security: encrypt EOA private key with keystore JSON#34
hadv wants to merge 3 commits intomasterfrom
hadv/eoa-keystore-output

Conversation

@hadv
Copy link
Copy Markdown
Owner

@hadv hadv commented Mar 24, 2026

Summary

  • Fix security vulnerability: The EOA vanity miner previously printed the raw private key to stdout, creating a data leak risk via terminal scrollback, shell logging, screen sharing, or piped output
  • Encrypted keystore output: Private key is now encrypted using the standard Ethereum Web3 Secret Storage format (scrypt + AES-128-CTR) and saved to a JSON keystore file with 0600 permissions — the same format used by geth account new
  • Memory safety: Raw private key bytes are zeroed from memory immediately after encryption
  • New CLI flags: --output/-o for custom file path, --password for scripted use, --light-kdf for faster encryption in testing

Security details

  • The raw private key is never printed to stdout
  • Interactive password prompt uses golang.org/x/term.ReadPassword() (no echo) with confirmation
  • Keystore file written with 0600 permissions (owner read/write only)
  • Private key material (big.Int bits and []byte slice) is explicitly zeroed after use

Usage

# Interactive password prompt (recommended)
./vaneth --mode eoa -p 0xABC

# Scripted with password flag
./vaneth --mode eoa -p 0xABC --password mypassword -o mykey.json

# Use lighter KDF for testing
./vaneth --mode eoa -p 0x00 --light-kdf --password test

Test plan

  • go build ./... compiles cleanly
  • go vet ./... passes
  • go test ./... passes
  • Manual test: run EOA miner with --light-kdf --password test, verify keystore JSON is written
  • Manual test: verify keystore can be imported into geth or another Ethereum wallet
  • Manual test: verify interactive password prompt works with confirmation

🤖 Generated with Claude Code

hadv and others added 3 commits March 24, 2026 10:09
The EOA vanity miner previously printed the raw private key to stdout,
creating a data leak risk via terminal logs, screen capture, or piped
output. Now the key is encrypted using the standard Ethereum Web3 Secret
Storage format (scrypt + AES-128-CTR) and saved to a JSON keystore file
with 0600 permissions. The raw key is never printed and is zeroed from
memory after encryption.

New flags: --output/-o, --password, --light-kdf

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Use unix.Mlock() to lock private key memory pages, preventing the OS
from swapping them to disk where they could be recovered. The memory
is unlocked with Munlock() after the key bytes are zeroed.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
big.Int.Bytes() strips leading zeros, which causes crypto.ToECDSA to
reject keys shorter than 32 bytes with "invalid length, need 256 bits".
Use FillBytes to always produce a fixed 32-byte slice.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant