Hardware wallet · 12 min read

Trezor Passphrase Recovery

The Trezor PIN is enforced by the secure element and uncrackable. The Trezor passphrase — the optional "25th word" that creates a hidden wallet — is computed off-device with vanilla BIP39 PBKDF2 and is recoverable if you have the seed and one known address. This guide explains the math, the tooling, and why the two security mechanisms are completely different.

The most common confusion among Trezor users: "I forgot my PIN — can you brute-force it?" No. "I forgot my passphrase — can you brute-force it?" Yes, often. Same device, completely different security models. This guide is about the second case.

Required artifacts: To recover a passphrase you need (1) the 12 or 24-word BIP39 seed AND (2) at least one address you know belongs to the hidden wallet (from a blockchain explorer history, a screenshot, an exchange withdrawal record). Without both, brute force has no oracle to check against.

PIN vs passphrase — the architectural split

PropertyPINPassphrase (25th word)
Where verifiedOn-device secure elementOff-device (in Trezor Suite / wallet)
AlgorithmDevice-specific protected memoryPBKDF2-HMAC-SHA512, 2048 iter
Rate limitExponential, then wipeNone — unlimited offline tries
Offline brute forceImpossibleYes — main attack surface
Recovery if forgottenWipe + restore from seedBrute-force with seed + address

The math: how the passphrase becomes a wallet

# BIP39 master seed derivation (RFC):
seed = PBKDF2-HMAC-SHA512(
    password = mnemonic_normalized,         # NFKD UTF-8
    salt     = b"mnemonic" + passphrase,    # passphrase is the variable
    iterations = 2048,
    dklen      = 64
)

# Master node from seed:
master_key, master_chain = HMAC-SHA512(b"Bitcoin seed", seed)

# BIP44 derivation for first BTC receive address:
# m/44'/0'/0'/0/0
# At each step, address can be matched against blockchain.

The crucial point: the passphrase enters the formula as a variable in PBKDF2. Different passphrase string → different seed → different master key → different addresses. Empty passphrase produces the "standard" wallet; "hello" produces a hidden wallet; "Hello" produces yet another hidden wallet. There is no integrity check inside the wallet — every passphrase is "valid" but only one matches your known address.

Brute-forcing with btcrecover

# Build a passphrase candidate list
cat > pass.txt <<EOF
mydog2017
MyDog2017
mydog2017!
MyDog2017!
mydog17
mydog2018
EOF

# Run btcrecover with seed + known address
python3 seedrecover.py \
    --bip39 \
    --mnemonic "abandon abandon abandon ... about" \
    --addrs bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
    --addr-limit 20 \
    --passphrase-list pass.txt

# Or with a tokenlist (combinator-style)
python3 seedrecover.py \
    --bip39 \
    --mnemonic "abandon abandon abandon ... about" \
    --addrs bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh \
    --addr-limit 20 \
    --passphrase-tokenlist tokens.txt \
    --typos 2 --typos-case

GPU acceleration with hashcat

Hashcat mode 12700 implements MyEtherWallet/BIP39 PBKDF2 derivation. For passphrase recovery you can pre-derive seed+passphrase, then check the resulting address externally — but the cleaner path is mode 28200 (electrum 2.x) for Electrum, or a custom address-matching pipeline.

GPUBIP39 PBKDF2 derivations / s10M candidate runtime
RTX 4090~50,000~3.3 min
RTX 3090~30,000~5.5 min
CMP 90HX~22,000~7.5 min
Single CPU core~3,000~55 min

Building a smart candidate list

For most users the passphrase is short, memorable and predictable. Common patterns:

  • Pet / kid / spouse name + year (e.g. Bella2017)
  • City of birth or important date (Lisbon1985)
  • Capitalized phrase (Send It, HodlForever)
  • Single common word (password, bitcoin)
  • Crypto inside joke (WenLambo, NotYourKeys)
  • Empty string (yes, many users set "passphrase" but never typed one — empty is valid)
Operational security: If you brute-force a passphrase on an internet-connected machine, the seed AND passphrase will at some point be in process memory. Do this on an offline laptop, ideally a Tails USB session, and immediately after recovery send funds to a fresh wallet derived from a brand-new seed. Assume the old passphrase is compromised.

Recoverable vs not

Recoverable

  • • Seed + at least one known hidden address
  • • Short passphrase from human memory
  • • Tokenlist of candidate words
  • • Empty passphrase (test this first!)

Not recoverable

  • • PIN forgotten + no seed backup
  • • Passphrase forgotten + no seed
  • • Passphrase forgotten + no known address
  • • Random 20+ char passphrase, no fragments

Related guides

Frequently asked questions

Difference between Trezor PIN and passphrase?

PIN is on-device, rate-limited, NOT recoverable. Passphrase is the BIP39 25th word, derived off-device, IS recoverable with seed + known address.

How is the passphrase wallet derived?

PBKDF2-HMAC-SHA512(mnemonic, "mnemonic" + passphrase, 2048 iter, 64 bytes). Output is the BIP32 master seed.

How fast can a passphrase be brute-forced?

CPU: thousands per second. GPU: tens of thousands per second. A 1-million-entry list runs in minutes.

What is plausible deniability mode?

Every passphrase produces a valid wallet, so an attacker cannot tell which is "real" without checking the blockchain. Same feature makes brute force tractable.

Can the PIN be recovered?

No. Wipe the device after enough wrong attempts and restore from seed.

Recover a forgotten Trezor passphrase

Send us your seed (or just the passphrase candidate list with a derived xpub), one known address from the hidden wallet, and any password fragments you remember. We run the address-matching attack on multi-GPU hardware. Pay only on success.