how to recover Bitcoin from old storage formats

19 replies 322 views
0x5e3dFull Member
Posts: 103 · Reputation: 519
#1Nov 24, 2020, 10:56 PM
Background I've noticed a lot of threads about recovering strange old wallets, and the solutions are usually pretty simple if someone can pinpoint the format. With the number of formats likely increasing, I expect more folks will forget how they stored their Bitcoin a decade ago or more. So, I thought it would be helpful to put together a comprehensive overview for anyone who stumbles upon Bitcoins in various storage formats. Work in progress This is still a work in progress. If you know of any formats that I've missed or have extra info to share, please chime in so I can update the main post and give you a shout-out. I haven’t tried every single wallet myself, and I definitely don’t claim to know all the formats out there. If you see a thread asking about a format that I haven’t covered, please share the link. Warning: take security precautions First off, make sure to create one or more backups (shoutout to DaveF)! You don’t want to work on your only copy, or you might end up losing everything. Know what you’re doing before diving in! If you’re unsure, just hold off. Ignore or report any unsolicited DMs from both old and new users. Talk about your needs publicly here, but whatever you do, don’t share your private keys, seed phrases, or wallet files. Don't trust any "help" via PM, or you'll probably get scammed. Be cautious with the screenshots you share. Never trust anyone with your private keys unless you're completely sure you’d trust them with the same cash amount.
3 Reply Quote Share
Posts: 28 · Reputation: 129
#2Nov 27, 2020, 06:37 AM
When recovering the wallet.dat or the default_wallet OR ANY OTHER ACTUAL FILE. MAKE A BACKUP ON REMOVABLE MEDIA BEFORE DOING ANYTHING. Hell make several, just in case. Let me bold that a bit more: MAKE A BACKUP ON REMOVABLE MEDIA BEFORE DOING ANYTHING. Don't put it in your Dropbox / google drive / Microsoft one drive. Just keep it local on media you control. This way if you damage the file for whatever reason, no big deal. And when you are done, you can destroy the media and know 100% it's gone. -Dave
5 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#3Nov 27, 2020, 06:56 AM
Added. I can't believe I forgot this one I don't want to recommend using newer formats for reasons of compatibility. It can be a complication on a fork, that's why I'll leave it up to the user to decide. SegWit has it's benefits, but to me a (paper wallet with a) legacy private key feels as if it will be much easier to recover 20 years from now. To keep the OP compact, I'll add a link to this post. I was hoping to add another link to a better and easier explanation about SegWit, but I mainly find websitse about it's activation. Added.
4 Reply Quote Share
Posts: 33 · Reputation: 177
#4Nov 27, 2020, 09:42 AM
Why not link directly to the BIP39 word list as well? https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md It is also worth noting that 24 word seed phrases are also fairly common (eg. Trezor One, Ledger Nano S)
3 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#5Nov 27, 2020, 03:30 PM
The "12 words" is my placeholder for something that's still incomplete I have no experience with hardware wallets, so I'll have to search when to use how many words. Update: I've added this section, and added your link. Please post if there's more to add.
4 Reply Quote Share
alex1337Member
Posts: 3 · Reputation: 75
#6Nov 27, 2020, 07:27 PM
This might sound a bit stupid but in your thread there are a couple of links and the text (offline!!) following those links. At first I thought you meant those links weren't available at the moment. But I realize you mean you should never enter sensitive stuff like seeds or private keys in an online environment. Maybe you could make the warning a bit clearer? Nice list/start btw
3 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#7Nov 28, 2020, 01:37 PM
The red "offline" links to my big Warning header. How about this: "do this offline!!"?
3 Reply Quote Share
alex1337Member
Posts: 3 · Reputation: 75
#8Nov 28, 2020, 03:13 PM
Sounds great! I know the old one probably would be good enough for most people but somehow you will always run into a few slower ones like me
4 Reply Quote Share
wagmiMember
Posts: 25 · Reputation: 111
#9Nov 30, 2020, 04:12 AM
Apart from the fact that that particular key was missing 7 characters do you have any other reason for saying this? The reason I am asking this is because I can't think of any reason why checksum would be 7 characters! Maybe I am missing some mathematical facts but AFAIK checksum is 4 bytes and 4 bytes encoded with base58encoding will give you between 4 chars to 6 chars. 4 chars being {0, 0, 0, 0} which is equal to 1111 and 6 chars being  {255, 255, 255, 255} which is equal to 7YXq9G. I also ran some random tests for fun and I didn't get a single 7 char! Also do you have any idea how such keys missing last characters are technically being recovered, apart from the obvious "import it in bc.i"?
0 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#10Nov 30, 2020, 07:24 AM
No, not really. Back when I was dealing with this case, I couldn't find any other way to restore the checksum for the private key. You could be right, I can't really tell at this point. I don't know, that's why I was happy to use that option. It gets weirder: if I import this into blockchain.info's wallet as a test, without the last 7 characters: I get a different bitcoin address than bitaddress.org gives me. If I try to import the complete private key, blockchain's wallet doesn't accept it. If I import the compressed version of the same private key, blockchain.info's wallet gives the right address: I'll add a link to this post to the OP, as it's unclear what this information is worth at this moment.
4 Reply Quote Share
Posts: 33 · Reputation: 177
#11Nov 30, 2020, 11:05 AM
Encoding the whole private key + checksum in Base58 is not the same as encoding both separately and then concatenating the result. For example let's use the (hashed) private key from the Bitcoin wiki [1] and encode it in Base58 [2]: Private key + checksum in hex: Private key + checksum in Base58: Private key without checksum in hex: Private key without checksum in Base58: Checksum only in hex: Checksum only in Base58: You see the difference? In hex 2 characters equal 1 byte (e.g. 0xFF = 0b11111111, i.e. 8 bits). In Base58 2 characters equal something like 1.375 byte (e.g. ZZ = 0x0760 = 0b11101100000, ie. 11 bits but then again not really). Hence when trying to remove the checksum by truncating the string of a Base58 encoded private key you lose a few more (or less) bits than intended. [1] https://en.bitcoin.it/wiki/Wallet_import_format [2] https://incoherency.co.uk/base58/
4 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#12Dec 1, 2020, 04:57 AM
I stumbled upon this post: I haven't tested or verified it. I'm quoting the script to ensure it's availablility: I invite anyone who's tested this to share the results.
3 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#13Dec 1, 2020, 06:47 AM
If you made a mistake writing down your seed phrase, and one or more words are missing, you may still be able to brute-force it: I haven't tested or verified it. I invite anyone who's tested this to share the results.
0 Reply Quote Share
atlas_2015Senior Member
Posts: 151 · Reputation: 999
#14Dec 3, 2020, 10:24 AM
Hey Loyce, Didn't multibit use wallet.dat(s) too? Also the two libraries on that python script above look like they're not default ones (so you have to download them)... EDIT: The andreas shildbach wallet backups were files without an extension and by default had the name Bitcoin-Wallet-Backup-Date
2 Reply Quote Share
0x5e3dFull Member
Posts: 103 · Reputation: 519
#15Dec 4, 2020, 10:41 PM
I'm not sure. I've tested multibit in the past, but didn't like it and don't remember it's file format. If you can help me out with a link, that would be much appreciated! I have this one listed already.
2 Reply Quote Share
atlas_2015Senior Member
Posts: 151 · Reputation: 999
#16Dec 5, 2020, 07:16 AM
Probably best to wait for HCP to confirm that one. https://github.com/richardkiss/pycoin at a guess I'd say it's this, I don't like the idea of installing custom modules on my python though... I think electrum had an MPK before the seed (master private key) and since it was before the creation of the seed, they look really odd (someone sent me one ofter they'd cleared the funds but that was about 2 years ago so I'll have no look in trying to find it, I think they were in hexadecimal format instead so they didn't have the xprv/xpub stuff but I'm not entirely sure as it was so long ago that they wre used...
3 Reply Quote Share
Posts: 5 · Reputation: 77
#17Dec 5, 2020, 11:36 AM
A bit off-topic, but i hope that's fine because this is worth to note and might be helpful: Python allows to create virtual environments. This allows to install custom modules to be used by a single application instead of installing them system-wide. Your 'standard' (system- and user- wide) python installation will remain untouched.
4 Reply Quote Share
atlas_2015Senior Member
Posts: 151 · Reputation: 999
#18Dec 5, 2020, 03:55 PM
I did and it installed the module (if it's good enough for them, it's good enough for me, also I don't actually have any funds/private keys or anything on this computer)... It returned this, I'm not entirely sure why The private key has had a history but I guess it's that reddit users'
3 Reply Quote Share
alex1337Member
Posts: 3 · Reputation: 75
#19Dec 5, 2020, 07:48 PM
Looking at the code: it uses an invalid wif(5KgbGQiriNxxwMKgdpwmu5ZsYyXBuBaCg7es9z5xznAnCEHzy51) and then replaces a character with every possible value. So every time this leads to a different wif to check. The result you see counting from 1..50 is the position where it tries the different possible values. A success was found by replacing the third character from a "g" to "f" leading to a valid wif. Incorrect wif at start: 5KgbGQiriNxxwMKgdpwmu5ZsYyXBuBaCg7es9z5xznAnCEHzy51 Corrected to: 5KfbGQiriNxxwMKgdpwmu5ZsYyXBuBaCg7es9z5xznAnCEHzy51 All the other substitutions didn't lead to a valid wif, that's why you see the counter go up to 50 without any other success messages. Disclaimer: I'm not the author of the code just explaining the code
3 Reply Quote Share
wagmiMember
Posts: 25 · Reputation: 111
#20Dec 6, 2020, 01:45 AM
If using it for missing 1 char, it doesn't matter but FWIW there seems to be a couple of bottlenecks in this function that will slow things down drastically. First is the fact that each time an invalid key is passed to this function it raises an exception. I have 0 experience in Python but in C♯ throwing exceptions is "expensive" apparently it is not so different in python either[1]. This can be changed to simply returning false if the key is invalid. This will probably make things faster at least 10 times (not benchmarked) Second thing I could notice is that it is converting the input back to a bignum (or what we call BigInteger) and then converts it back to a byte array and starts performing hashes (for checksum) on it. This step is slow and unnecessary. Converting the base58 input directly to base256 (byte array) made it 6 times faster (I did benchmark this!) [1] https://stackoverflow.com/questions/2522005/cost-of-exception-handlers-in-python
4 Reply Quote Share

Related topics