Hands-on guide · 15 min read

Paper Wallet Recovery and Import

A complete, technically accurate guide to moving coins from a paper wallet into a modern software wallet — including what to do if the paper is faded, torn, or password-protected with BIP38.

Paper wallets were the canonical cold-storage solution of 2013 through 2017 and are still the physical form factor millions of long-term holders relied on. If you are dusting off a folded envelope with a pair of QR codes and a long string starting with 5 or K or L, this guide explains exactly what you have, how to move the coins safely, and what to do if the paper is damaged.

Golden rule of paper wallets: once you have shown a paper wallet's private key to any software, consider the address permanently compromised. Always sweep the funds to a fresh address in a new wallet; never reuse the paper's address to receive more coins.

Anatomy of a paper wallet

The classic paper wallet contains two strings and their QR codes:

Public address (safe to share)

Starts with 1 (legacy P2PKH), 3 (P2SH), or bc1 (bech32 SegWit). Derived from the private key through RIPEMD-160(SHA-256(pubkey)). Used only for receiving.

Private key / WIF (NEVER share)

Starts with 5 (uncompressed), K or L (compressed), or 6P (BIP38 encrypted). 51 or 52 characters, Base58Check-encoded. Signs transactions.

WIF (Wallet Import Format) is Base58Check over a concatenation of a version byte (0x80 for mainnet), 32 bytes of raw private key, an optional 0x01 compression flag, and a 4-byte SHA-256 checksum. That checksum is what lets us recover partially damaged paper wallets — a single random 32-byte key has only a 1 in 4.3 billion chance of accidentally passing the checksum, so brute-forcing unknown characters converges reliably on the right value.

# WIF structure (uncompressed mainnet)
[0x80]              version byte, 1 byte
[32 bytes]          private key (256-bit integer, big-endian)
[4 bytes]           SHA256(SHA256(version + privkey))[:4] checksum

# Base58Check encode → starts with '5', total length 51 chars

# WIF compressed (adds 0x01 before checksum)
[0x80][32 bytes privkey][0x01][4 bytes checksum] → starts 'K' or 'L', 52 chars

Sweep vs Import — the crucial distinction

Sweep (recommended)

Builds a transaction that sends all UTXOs at the paper address to a fresh address in your new wallet. After the transaction confirms, the paper's private key controls nothing — even if it is later photographed, stolen, or leaked.

Import (dangerous)

Adds the paper key to your software wallet as one of its addresses. The coins stay at the paper address. Anyone who has ever seen the paper — courier, photographer, maintenance staff — can still spend the funds at any future date.

Sweeping in Electrum (the easy path)

Electrum has the cleanest sweep UX of any Bitcoin wallet. If you are non-technical, use this.

  1. Download Electrum from electrum.org and verify the GPG signature — malicious forks have historically stolen sweeps.
  2. Create a new standard wallet with a fresh seed phrase. Write that phrase on paper; this is your new cold backup.
  3. Open Wallet → Private Keys → Sweep from the menu.
  4. Paste the WIF private key from your old paper wallet into the dialog.
  5. Choose a destination address from your new wallet (Receive tab → first address).
  6. Set the fee to "normal" unless you are in a hurry; press Sweep. Electrum broadcasts immediately.
  7. Wait one confirmation (~10 minutes). Then physically destroy the old paper — shred, burn, soak. Never keep it "just in case".

Sweeping in Bitcoin Core (the technical path)

Bitcoin Core 0.21+ dropped the old importprivkey RPC in favour of descriptor wallets. Sweeping is a two-step process:

# 1. Create a temporary watch-only descriptor wallet for the paper key
bitcoin-cli createwallet "paper-sweep" false true "" true

# 2. Import the paper wallet's WIF as a single-key descriptor
# (replace <WIF> with the actual key; get the descriptor checksum via:)
DESC=$(bitcoin-cli getdescriptorinfo "combo(<WIF>)" | jq -r .descriptor)
bitcoin-cli -rpcwallet=paper-sweep importdescriptors \
    "[{\"desc\": \"$DESC\", \"timestamp\": \"now\", \"label\": \"paper\"}]"

# 3. Rescan the blockchain for UTXOs at this address (may take hours)
bitcoin-cli -rpcwallet=paper-sweep rescanblockchain

# 4. Send everything to your main wallet's fresh address
ADDR=$(bitcoin-cli -rpcwallet=main getnewaddress)
bitcoin-cli -rpcwallet=paper-sweep sendtoaddress $ADDR 0 "" "" true

# 5. Delete the temporary wallet
bitcoin-cli unloadwallet "paper-sweep"

Sweeping in BlueWallet (mobile)

BlueWallet on iOS and Android supports paper wallet sweep via the QR scanner.

  1. Open an existing on-chain wallet in BlueWallet (or create one first).
  2. Tap Send, then the QR-scan icon, then Scan or paste a private key.
  3. Scan the private-key QR from your paper. BlueWallet detects it and offers to sweep.
  4. Confirm the destination address (your own wallet) and broadcast.

Reconstructing a damaged paper wallet

If you cannot read every character of the WIF, do not despair — the checksum lets us brute-force a surprising amount. For each unreadable character you try all 58 Base58 alphabet values; for N missing characters you test 58^N candidates and keep the ones whose recomputed SHA-256 checksum matches the surviving bytes. Additionally, you can validate candidates by deriving the public address and checking whether it matches the address printed on the paper (which is usually still readable even when the private key has faded).

# Python sketch: brute force up to 5 missing characters
import itertools, hashlib, base58

BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
known = "5Kb8kLf9zgWQnogi???C3yZv8YqoPqKB9vN5Pz1sQBCV6aP7vPa"  # 3 unknowns
expected_addr = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"

positions = [i for i, c in enumerate(known) if c == "?"]
for combo in itertools.product(BASE58, repeat=len(positions)):
    trial = list(known)
    for i, p in enumerate(positions):
        trial[p] = combo[i]
    wif = "".join(trial)
    try:
        raw = base58.b58decode(wif)
    except Exception:
        continue
    body, check = raw[:-4], raw[-4:]
    if hashlib.sha256(hashlib.sha256(body).digest()).digest()[:4] != check:
        continue
    # checksum valid → derive address and compare
    from ecdsa import SigningKey, SECP256k1
    priv = body[1:33]
    sk = SigningKey.from_string(priv, curve=SECP256k1)
    # (full address derivation omitted for brevity)
    print("candidate:", wif)

Practical limits: 0–3 unknown characters recover in seconds, 4–5 in minutes, 6 in hours on a laptop. From 7 missing characters the search hits 3.6 billion combinations and you need GPU support; beyond 8 it is not feasible without a major commercial rig. The btcrecover tool has built-in WIF brute force with typo modelling.

BIP38-encrypted paper wallets

If your paper wallet's private key starts with 6P, it is encrypted under BIP38. BIP38 uses Scrypt with parameters N=16384, r=8, p=8 — by design slow, so that brute forcing a password costs real compute even on GPUs. You need the original password to decrypt and use the key.

# BIP38 decrypt with known password (in Python)
pip install bitcoinlib
python3 -c "
from bitcoinlib.keys import Key
k = Key(import_key='6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg',
        password='MyPassword123')
print(k.wif())
"

# BIP38 brute force with hashcat mode 15400
python3 bip38_2john.py paper.txt > bip38.hash
hashcat -m 15400 bip38.hash candidates.txt -w 3

# On a 3090: ~9 KH/s, on a 4090: ~15 KH/s
# 8-character lowercase+digit → 2.8T candidates → 3.6 years single GPU
# Only realistic with strong hints narrowing to <100M candidates
Realistic BIP38 odds: if you remember the password entirely, trivial. If you remember pieces (base word, length range, whether digits were appended), commercial GPU services recover roughly 35 % of submitted BIP38 papers. If the password is genuinely random above ten characters, not recoverable.

Common paper wallet mistakes

  • Importing instead of sweeping. See above — the paper remains a risk forever.
  • Reusing the paper address after a partial sweep. Once any software has touched the key, it is burned. Never send new deposits to a paper address you have already accessed online.
  • Generating the paper wallet on an online JavaScript site. Many such sites had backdoors that siphoned keys. If your paper came from bitaddress.org generated online rather than offline, sweep immediately — your address may already be scheduled for theft.
  • Laminating. Cheap laminators use heat-activated glue that yellows and can lift the printer toner, destroying characters. Use acid-free sleeves instead.
  • Inkjet printing. Inkjet ink fades dramatically within five years. Always use laser.
  • Single copy. House fires happen. At minimum two physical copies in two locations.

After the sweep: hygiene

Once the sweep transaction confirms:

  1. Physically destroy the paper — cross-cut shred plus burn, or soak in bleach.
  2. Record the date and transaction ID of the sweep in your records.
  3. Never, ever send more coins to the old address, even "by accident". Delete it from your address book.
  4. Back up the new wallet's seed phrase in metal (Cryptosteel, Blockplate) rather than paper for durability.
  5. If you used Electrum online, confirm no malware replaced the destination address at the last moment. Check the transaction on a block explorer.
Related reading: for BIP38 password brute force see our btcrecover tutorial; for storage alternatives after you sweep, our hardware wallet guide covers the modern cold-storage upgrade path.

If the key is BIP38 and you have forgotten the password

Send the 6P-prefixed string to our recover page along with any hints you have about the original password. Our GPU farm runs hashcat mode 15400 against targeted candidate sets; typical recovery runs on a hint-rich BIP38 paper take between one and six days and you pay only if the password is found.

Last updated 2026-04-21. Sweep procedures verified against Electrum 4.5.5, Bitcoin Core 26.0, and BlueWallet 6.6.