☎ +1 214-659-1775 Signal: +1 214-659-1775 [email protected]
Mon–Fri 9:00–18:30 MT · Denver, Colorado

wallet.aes.json: what the Blockchain.com backup file actually is

David Veksler By David Veksler Sep 16, 2026 13 min read Guides

wallet.aes.json is the file a Blockchain.info or Blockchain.com "My Wallet" backup lives in. Almost every "decrypt failed" message people bring us starts with a misunderstanding of what that file is, because one filename covers several different wrapper formats and two separate layers of encryption. This is a reference page: what the file is, how to tell which version you are holding, how it is encrypted, and what each record inside a decrypted wallet means. If you want the diagnostic steps for a backup that will not open, they are in Blockchain.com backup file won't decrypt, and the service page is Blockchain.com wallet recovery.

What is a wallet.aes.json file?

Locked out of a wallet like this one?

I repair hardware wallets, crack forgotten passwords, and rebuild broken seed phrases — on my own bench in Denver.

✓ NO FEE UNTIL YOUR CRYPTO IS BACK · FREE ASSESSMENT
Get a free assessment →

A wallet.aes.json file is one AES-encrypted JSON payload that holds an entire Blockchain wallet: its private keys, its HD seed, its address labels, and its transaction notes. It is not a text file you can read, it does not contain your balance, and it is not tied to Blockchain's servers once you have it. Your balance lives on the blockchain; the file holds the keys that prove the coins are yours, which is why a copy of the file is a copy of the money.

Unlike a desktop wallet's database, this file was designed for a hosted wallet. Blockchain kept the encrypted blob and handed it back to your browser, which decrypted it locally with your password. wallet.aes.json is that same blob saved to disk, either through the wallet's own backup export or pulled from Blockchain's servers with your Wallet ID. That origin explains the file's two most confusing traits: it is often a single unbroken line of base64 with no structure a person can see, and it can carry a second password that the login password never touches.

Which format do I have? Check the outer shape

You do not need the password to answer this, and the answer changes which tool will open the file. There are three outer shapes, all called wallet.aes.json.

Shape Era What it looks like How it is read
Raw (v0 / v1) Earliest Blockchain.info wallets One long run of base64, no { and no JSON around it Treated as raw encrypted data
Config wrapper Some server exports JSON with a payload field but no version field The real wallet is nested inside payload
Versioned (v2 / v3 / v4) Modern wallets JSON {"version":N,"pbkdf2_iterations":I,"payload":"<base64>"} payload is the encrypted blob

Blockchain's own open-source wallet decides this the same way: it tries to parse the file as JSON, and "if parsing fails, treats as version 1 (raw encrypted string)"; if a wrapper is present it reads wrapper.version, wrapper.pbkdf2_iterations, and wrapper.payload (My-Wallet-V3 wallet-crypto.js, decryptWalletSync). A config file has no version attribute and instead "encapsulate[s] the wallet file plus some detritus", so the encrypted wallet has to be pulled out of its payload field first (btcrecover btcrpass.py, _parse_encrypted_blockchain_wallet).

This is the single most common reason a "good tool" reports a good file as broken: a decoder built for a versioned wallet is handed a raw v1 blob, or handed a config wrapper it does not know to unwrap, and fails on a file whose coins are perfectly intact.

If you would rather not judge this by eye, our free Blockchain.com backup file checker reports the shape, the version, and the iteration count, and, most usefully, whether the encrypted payload is complete or has lost bytes. It runs entirely in your browser, nothing is uploaded, and it never needs your password.

The version numbers, and what they actually mean

The version field inside a modern wrapper is the encryption version, not the wallet's feature set. Blockchain's public library defines SUPPORTED_ENCRYPTION_VERSION = 3, and its decoder "throws error if version > SUPPORTED_ENCRYPTION_VERSION" (My-Wallet-V3 wallet-crypto.js). Recovery tooling goes one further: btcrecover raises NotImplementedError only when data["version"] > 4, and its second-password handling reads a v4+ format: one xpriv per derivation/script-type, so a version 4 layout with per-derivation extended keys does appear in newer exports (btcrecover btcrpass.py).

For recovery, only two things about the version matter:

If you know roughly what year the wallet was created, that alone usually tells you whether you are dealing with a raw early file or a modern versioned one.

How wallet.aes.json is encrypted

Every versioned Blockchain backup is encrypted the same way, and the details are worth knowing because they explain both why the file is recoverable and why generic tools mishandle it.

From Blockchain's wallet-crypto.js:

That last point is the one to remember: the first sixteen bytes of the decoded payload are simultaneously the PBKDF2 salt and the AES-CBC initialization vector. btcrecover splits the file exactly this way, iv, encrypted = decoded[:16], decoded[16:], and derives the key with pbkdf2_hmac("sha1", password, salt_and_iv, iter_count, 32) (btcrecover btcrpass.py, decrypt_current).

The default for a new modern wallet is 5,000 PBKDF2-SHA1 iterations (defaultPbkdf2Iterations, from the merged getDefaultWalletOptions() in blockchain-wallet.js). Five thousand SHA1 rounds per guess is what makes a GPU the practical tool for a forgotten password and what makes the wallet's stored iteration count, rather than password length alone, set the pace. The full brute-force reasoning is in how I brute-force Blockchain.info wallets.

The ISO 10126 padding is why a "decrypt failed" message is so often misleading. Generic AES libraries expect PKCS#7 padding and reject the real final block even when the password is correct, so a tool that validates PKCS#7 will call a perfectly good decryption a failure. A wrong password and a padding-scheme mismatch produce the identical error, which is a large part of why people spend weeks attacking a password that was never the problem.

The oldest v0 / v1 raw files predate this settled scheme. Blockchain's own code tries several methods in order for them: CBC with ISO 10126 at 10 iterations, then OFB with no padding at 1 iteration, then two more variants (wallet-crypto.js, the decryptFns list). If a very old backup will not open in a modern tool, this is usually why: the tool never tries the old modes.

What is inside a decrypted wallet

Once the outer password decrypts the payload, the plaintext is a JSON wallet object. Recovery tools recognise a correct decryption by looking for these field names in the first block, which is also the cleanest list of what a Blockchain wallet contains. btcrecover matches on: guid, sharedKey, double_encryption, dpasswordhash, metadataHDNode, options, address_book, tx_notes, tx_names, keys, hd_wallets, paidTo, and tag_names (btcrecover btcrpass.py, matchStrings).

The ones that matter for recovery:

Field Meaning
guid The wallet identifier, the same GUID as your Wallet ID
sharedKey A per-wallet secret used as the salt for the second-password hash. Not your password
double_encryption Boolean. true means a second password is set and the keys are locked behind it
dpasswordhash The stored verifier for the second password, a 32-byte hex hash
options Wallet settings, including pbkdf2_iterations, fee_per_kb, logout_time
keys The array of imported / legacy addresses, each with a priv private key
hd_wallets The HD wallet(s): each has accounts, each account an xpriv (v3) or per-derivation xpriv (v4)
address_book Saved send-to addresses and their labels
tx_notes / tx_names Your private notes and names on transactions
metadataHDNode The key for Blockchain's metadata service

Two practical points follow from this list.

The keys array and the hd_wallets array are two different pots of coins. Old Blockchain wallets held a flat list of individually generated keys; the HD upgrade added hd_wallets with a seed behind it. A wallet can hold both, and a restore that recovers one but not the other will show a balance that is too low. The version marker Blockchain uses internally is exactly this distinction, "version 2.0 (legacy, non-HD) versus 3.0 (HD-upgraded)" (wallet.js).

A note on where the fields live. btcrecover's own comment records that the layout has drifted: the guid "no longer appears in the first block" as of May 2020, and tx_notes appears there instead. This is harmless for recovery but explains why a check that hunts for one specific field name can miss a good decryption of a newer file.

The two encryption layers inside a Blockchain.com wallet.aes.json backup A Blockchain.com wallet.aes.json backup has two locks. The file on disk is a wrapper carrying a version number, a PBKDF2 iteration count, and an encrypted payload whose first 16 bytes serve as both salt and IV. The outer login password, stretched with PBKDF2-SHA1 and applied through AES-256-CBC, decrypts the payload into a plain JSON wallet: guid, sharedKey, options, address book, transaction notes, the flat keys list, the HD wallets, and the double_encryption flag with its dpasswordhash verifier. When double_encryption is true, a second password keyed on sharedKey still encrypts every priv, xpriv, and seedHex individually, so the wallet is visible but nothing can be spent. The outer password must be recovered first because sharedKey only comes out of a decrypted wallet. The two locks inside a wallet.aes.json file OUTER PASSWORD, THEN SECOND PASSWORD 1. THE FILE ON DISK wallet.aes.json A wrapper, or for the oldest wallets a bare base64 string. Nothing here is readable, and none of it is the balance. version: the encryption version (2, 3, or 4), absent on raw v0 / v1 files pbkdf2_iterations: how many times each password guess is stretched (5,000 by default) payload: the encrypted blob; its first 16 bytes are both the PBKDF2 salt and the AES-CBC IV 2. OUTER PASSWORD UNLOCKS THE STRUCTURE PBKDF2-SHA1 + AES-256-CBC The login password decrypts the payload into a plain JSON wallet. This is as far as "I can log in" gets you. guid, sharedKey, options, address_book, tx_notes, tx_names keys: the flat list of imported and legacy addresses hd_wallets: the HD accounts and the seed behind them double_encryption and dpasswordhash: whether a second lock is set, and its verifier 3. SECOND PASSWORD UNLOCKS THE COINS only when double_encryption is true Each private key stays individually encrypted behind a separate password, keyed on sharedKey plus that password. Without it you can see every address and move nothing. priv on every entry in keys xpriv on every HD account, and seedHex on the HD wallet Verified against dpasswordhash, so it can be searched offline like the outer password ORDER the outer password has to be recovered first, because sharedKey, the salt for the second lock, only comes out of a decrypted wallet.
Two separate passwords, two separate jobs. The login password opens the wallet's structure; the second password, if one was ever set, is what actually frees the keys.

The second password, and "I can log in but can't spend"

This is the trap that catches more Blockchain users than any other, and it is a genuinely separate layer of encryption.

When double_encryption is true, your main password decrypts the wallet structure, but every private key stays encrypted behind a second password. You can log in, see your addresses and balance, and still be unable to move a single satoshi, because the priv, xpriv, and seedHex fields are individually encrypted (blockchain-wallet.js, the encrypt() method).

The second password is verified, not stored. Blockchain computes passwordHash = hashNTimes(sharedKey + inputString, iterations) and compares it to the saved dpasswordhash (blockchain-wallet.js, validateSecondPassword). That hash is iterated SHA-256 of the shared key concatenated with your second password, using the wallet's options.pbkdf2_iterations count; older wallets used a single SHA-256 hash or exactly ten (btcrecover btcrpass.py, WalletBlockchainSecondpass). Note that the second-password verifier uses plain iterated SHA-256, while the per-key field encryption uses the same PBKDF2-SHA1 and AES-CBC as the outer layer, keyed on sharedKey + password.

Three consequences matter if this is you:

The legacy mnemonic is not a modern seed phrase

Blockchain's older HD wallets used a recovery phrase that does not behave like a standard BIP-39 seed, which is why one so often "restores an empty or wrong wallet" in another app. That is a distinct problem with its own reference: recovering a Blockchain.com Wallet ID and the legacy mnemonic, and the general "right seed, wrong derivation path" case is covered in seed phrase restored an empty wallet. The short version: a phrase that restores nothing is usually a derivation-path or format problem, not proof the coins are gone.

What wallet.aes.json is not

It is not a downloadable balance. Searches for a "wallet.aes.json with funds" reach files that are bait: encrypted with a password you will never have, empty of spendable coins, carrying malware, or set up so any coins you move are swept away by a script watching the address. There is no honest version of this. If you are looking because you are trying to recover your own money, the pages above are the real path, and how to spot a fake recovery service covers what happens to people who go looking in that part of the internet.

It is not readable without the password. "Decrypt failed" is the same message for a wrong password, a truncated file, and a wrong-format tool. Settling which of the three you have is the whole first hour of a real case, and it is what the backup file checker exists to answer without a password.

It is not safe to hand to a stranger. A copy of the decrypted wallet is a copy of the coins. Nobody legitimate needs your wallet file to give you a quote, and nobody legitimate contacts you first. That commitment, and what to check before trusting anyone with a wallet file, is on the scam warning page.

If you are stuck

A wallet.aes.json written years ago still holds spendable keys today. The reasons it will not open are almost always a recoverable password, a wrong-format tool, or a file that lost bytes when it was copied out of an email or a chat, and those are different jobs with different answers. Identify the shape and version first, work only on a copy, and never let the original be overwritten.

If you would rather not do that yourself, Blockchain.com wallet recovery is a service we run, and the wallet and key recovery tools survey lists the software worth trying first if you want to attempt it on your own.

Sources

David Veksler

David Veksler

Founder of WalletRecovery.info. Working in Bitcoin since 2013; recovering wallets for clients since 2017 through Veksler Consulting LLC (Colorado, USA). About David →

Locked out of your wallet?

Describe your situation and I'll tell you — for free — whether recovery is realistic. No fee until your coins are back.

Get a free assessment
+1 214-659-1775 · [email protected] · Mon–Fri 9:00–18:30 MT · Denver, Colorado