Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Provided AES key is wrong" when decrypting wallet #620

Open
clubshaft opened this issue Oct 11, 2014 · 149 comments
Open

"Provided AES key is wrong" when decrypting wallet #620

clubshaft opened this issue Oct 11, 2014 · 149 comments
Milestone

Comments

@clubshaft
Copy link

I have a serious bug ! import wallet work . I see all my transfers and my saldo ''coins''

when I wanna sent some coins it ask me for password . like it always do now monts from may .

I know my password 100% here is no doubt about it .

I get the error message ► provided AES key is wrong . this is insain ! ! ! why you let me enter a password to my wallet ? not safe without a password you tell to the people .
BULLSHIT + 20 BTC my own coins from 2 years pfffffff
I can do nothing with it becouse off that stupid password BUG ( scam?? )

Iam now 7 days trying to fix this but nothing work . coincidentally the backup wallet and backup key also give an error . all the other files are ok from my old wallets . they are all there but there is no money on it .

the error message was "NUL" wit the backup key and backup wallet file .

I'm totally misled by multibit WTF I I knew this was going to give problems . no recovery for passwords LOL so that is safe ????? never I read anny messages for warning me becouse the danger off using a password . I know my password let that be clear . more than 23 coins WTF .

████ people if you read this do your password gone before it is to late ! ! just rar the file with password two times or 3 times . up some rar with password in gmail there it stays till we dead .
for me it is to late feel verry bad what a massive scam damn ███

@clubshaft
Copy link
Author

I also try to import them in blockchain . I create there a wallet and try to import but that is not working annymore

@gary-rowe
Copy link
Contributor

gary-rowe commented Oct 11, 2014

We haven't stolen your bitcoins. Let's go through this step by step to help you unlock your wallet. Can I ask you to keep your responses to this issue to help me and others keep track of your progress. You may want to remove personally identifying information from your posts (don't reveal your balance and so on).

Next, can you verify that you've read the password recovery help article: https://multibit.org/en/help/v0.5/help_lostOrForgottenPassword.html

Note to readers in 2020 and later

This is an immense thread, filled with various dead ends. Please see this summary #620 (comment)

@clubshaft
Copy link
Author

if someone can tell me wich files I needed than I use a new hard disk with a clean instalation and run this disk in usb external modus to run get data back ntfs .

ps: yes sir I read that but like I say I know my password ! if I type it wrong that I get the message could not decrypt . . . . . . that is 100% wrong pass . but AESkey is wrong sorry but that is not my wrong .

@gary-rowe
Copy link
Contributor

OK, I need to establish a baseline of what you've already tried to recover the wallet. Can you tell me when the wallet was first created and in which version of MultiBit it was done?

@clubshaft
Copy link
Author

yes 2014-05-07 00:17:** I did my first transfer with that wallet . therefore I use an other wallet but that one is still ok .

@clubshaft
Copy link
Author

multibit vers 15 ► now I use vers 18 from last saturday after my lost coins ! !

back then I created that wallet 10 min later I make the password for it . is it posible that the recovery file that I have is before I enter an pass to it ?

the last good files are from september . but they give bold an error " NUL"
so I use the file from 05/2014 I search on date . all the other file are from my first wallet . tons and tons

@gary-rowe
Copy link
Contributor

Can you verify that you are using 0.5.18 as the wallet creator? It is very unlikely that the AES encryption key would have been mangled since MultiBit will check that it can decrypt the wallet with the given password before returning with a positive message.

When you add a password to a wallet MultiBit Classic will go over any backups it can find and apply the encryption to protect any previously unprotected keys. Unless your backups are outside of where it would normally expect to find them they should all be encrypted.

Here is some detailed technical information on the encryption used: https://github.com/jim618/multibit/wiki/Export-and-limited-import-of-private-keys

At this stage I would recommend that you switch to using OpenSSL to attempt decryption since it will be faster than through the MultiBit UI. You should target the .key file.

You should also pursue the possibility that you might have accidentally mistyped your password. It is definitely worth using the script in the password article referenced earlier to explore a variety of combinations rapidly. You can run the script using cygwin if you're on Windows.

@clubshaft
Copy link
Author

multibit vers 15 ► now I use vers 18 from last saturday after my lost coins ! !

@clubshaft
Copy link
Author

if I type it wrong than I always get coulsd not decrypt .. . . . . but i know the pass I use it + 20 times from 05/2014 till last saturday

@clubshaft
Copy link
Author

maibe I must uninstall version 18 and get back to 15 ?

@gary-rowe
Copy link
Contributor

What message is OpenSSL giving you when you attempt to decrypt using:

openssl enc -d -p -aes-256-cbc -a -in encryptedwallet.key -out decryptedwallet.txt -pass pass:yourpassword

Obviously you'll substitute your own values.

Don't rewind back to 0.5.15. I want to be sure that the problem is with the key file. You're adamant that you are typing in the correct password but that decryption is failing. That indicates a corrupted file but we have to be sure.

@clubshaft
Copy link
Author

are you related to the software sir ?

@gary-rowe
Copy link
Contributor

Yes, Jim is the primary developer of MultiBit Classic and I'm the secondary. I've asked Jim to keep an eye on this thread and he'll probably take over later since I have limited time available today.

@clubshaft
Copy link
Author

I now find the file multiwallet-qt.md is this helpfull ? search for the key file now

@gary-rowe
Copy link
Contributor

Don't know that file so it's probably not relevant. If you need to locate the .key file this article will assist you: https://multibit.org/en/help/v0.5/help_fileDescriptions.html

@clubshaft
Copy link
Author

have it . yesterday I rar it with pass and there I get it now becouse the other is missing .

ok here is my key located can you give me the exact code

j:\nul_error.key

@clubshaft
Copy link
Author

this whas the original key name bv-20140507000410.key

and thgis is the wallet bv-20140507000410.wallet

@clubshaft
Copy link
Author

that ssl stuff is chineese for me lol

@gary-rowe
Copy link
Contributor

Now that you have a .key file do the following (I've made the instructions step by step for Windows):

  1. Ensure you have OpenSSL installed.
  2. Open the command prompt and navigate to J:\ (on Windows type J: at the command prompt)
  3. Verify you can see the file: (type dir to see a list)
  4. Enter the following at the command prompt on a single line:
openssl enc -d -p -aes-256-cbc -a -in nul_error.key -out nul_error.txt -pass pass:yourpassword

Change yourpassword to your password.

OpenSSL will attempt to decrypt the file and will tell you if it is successful. The decrypted keys will be placed in nul_error.txt and should now be considered compromised. You'll need to sweep funds out of them as soon as possible into a safe area. If you have those keys you have your bitcoins.

You can see the key file format here: https://multibit.org/en/help/v0.5/help_exportingPrivateKeys.html

@clubshaft
Copy link
Author

I have win 7 64 bit do I need to download the win 64 vers ?

@gary-rowe
Copy link
Contributor

Sounds right. It'll tell you if it has problems.

@ghost
Copy link

ghost commented Oct 11, 2014

@clubshaft You don't need to download a Win 64 version - the Windows installer is 32 bit and should work fine

@clubshaft
Copy link
Author

ok I uninstall then becouse it not work

@ghost
Copy link

ghost commented Oct 11, 2014

This is being covered in issue #611.
As it's confusing having two issues open about the same thing I'll close this one.
Please post on #611 thanks.

@clubshaft
Copy link
Author

@clubshaft
Copy link
Author

no #611 have nothing to do with my problem ! my password is not working and it is the right one ! ! ! ! !

@clubshaft
Copy link
Author

Provided AES key is wrong ! I have the key file and ssl is instal now how to run it so I can encrypt like you explane to me

@ghost
Copy link

ghost commented Oct 11, 2014

Gary's post starting "Now that you have a .key file do the following (I've made the instructions step by step for Windows):" explains using OpenSSL step by step.

Please take the time to go through the suggestions step by step.

It is the same process effectively as doing an Tools | Import private keys but on the command line.

Also, in your original post you don't explain where you got your private key file export from.
That wallet will also have the private keys controlling your bitcoin. If that was a MultiBit wallet then it will have backups too that you might be able to use.

Note that your password is case sensitive and must match exactly (i.e. the same sort of hyphen, quote mark etc) or you won't be able to decrypt that file.

@gary-rowe
Copy link
Contributor

I've been working on this problem for the past few weeks and here are some definitive results as a result of a very detailed analysis across multiple versions of the code bases of MultiBit and Bitcoinj (the underlying library):

  • the MultiBit encryption/decryption of wallets is robust and did not mutate across versions
  • the wallet format provides the public keys of the encrypted private keys to allow for cross-checking the decryption
  • the message "Provided AES key is wrong" means precisely that "the given password apparently caused a decryption but when checked against the required public key turned out to be a false decrypt"

If one runs a password cracker over a MultiBit wallet there are multiple instances where the message "Provided AES key is wrong" is seen. When one provides the correct password the correct public key is derived from the decrypted private key.

In addition, I myself have sworn blind that I used one password to encrypt a wallet only to find that I actually used another one entirely unrelated. Our human memories are truly terrible.

So given the above, what can be done?

  1. Try to find an unencrypted version of the wallet.
  2. Get a list of other passwords that you've used in the past (perhaps you have a password manager that allows this) and work through them.
  3. Using the password list above enlist a tool like hashcat and use it to generate a vast number of candidate passwords and then work through them. You're now in the realm of professional crypto wallet cracking services.

Note that MultiBit does not use simple password hashing so a rainbow attack is useless. Instead a cracking tool would need to use the same code as present in MultiBit/Bitcoinj and work through the different candidates. This is a deliberately slow process (30-100 guesses per second offline) so any good guesses at existing passwords greatly reduce the search space.

@omnivorist
Copy link

Thanks for this @gary-rowe.
I am well aware that I might have forgotten my password - so I am not suggesting there are faults in MultiBit.

I am most interested in your last paragraph.
I have tried using btcrecover on the MultiBit key file configured to generate a huge number of candidate passwords - so far without success. What do you mean about this being a deliberately slow process. I appreciate that is not trivial but I would expect it to get faster using a faster processor, for example.
btcrecover apparently has the capability to run on fast graphics processors - reportedly with a 100x speedup. You're surely not saying that there is a hard limit to how fast it can run.

Or maybe I misunderstood your post.

@gary-rowe
Copy link
Contributor

gary-rowe commented Feb 22, 2021

@omnivorist MultiBit Classic uses Scrypt as a key derivation function with parameters N=16384, R=8, P=1. This has the effect of forcing a time constraint on processors in order to generate the resulting hash which is then used as the actual key for the AES (CBC padded) encryption of the private keys. These parameters were considered good for 2013 and a bit weak for 2017 and much less suitable for 2020 onwards. However, I should point out that this only applies to the keys within a .wallet file (a Protobuf serialization format).

If a key export has taken place (found in an encrypted .key file) then a different encryption process is used. This was in case MultiBit as a project was no longer available and a user needed a less complex format to work with. Thus a simple text file with AES encryption supported by OpenSSL was chosen.

The command line to access this file (usually in the key-backup folder) is

openssl enc -d -p -aes-256-cbc -a -in encryptedwallet.key -out decryptedwallet.txt -pass pass:yourpassword

and is much faster to decrypt.

A possible cracking script for MultiBit Classic .key files

Edit: There is a more refined script later:

Here is a simple Unix script for taking a list of guesses and applying them to the exported key file. Note that if you export your guesses from a key manager tool the output may be a CSV with multiple columns. You should adjust the ${print $123} to {print $1} if the guesses are in the first column and so on as needed.

#!/bin/bash
echo Usage: apply-guesses.sh [guesses CSV] [key file] 
echo Password file: $1
echo Key file: $2
for password in $( awk -F , -v OFS=' ' '{print $123}' $1 ); do
   echo ------
   echo Attempting: $password...
   openssl enc -d -p -aes-256-cbc -a -in $2 -out recovered.key -pass pass:$password
   if [ $? -eq 0 ];
     then 
       echo "Success!";
       break;
     else 
       echo "Failed";
   fi
   echo ------
done

Simply running it as is won't work you'll need a word list. The best way to get one is to first create a list of possible guesses in a text file called basis.txt and then run hashcat over them using a good rule like best64.rule or dive.rule from its repo to generate hashcat.txt.

You do this as follows (using Homebrew for installation, your OS may vary):

brew install hashcat
hashcat --force --stdout basis.txt -r rules/dive.rule > hashcat.txt
chmod +x apply-guesses.sh
./apply-guesses hashcat.txt encryptedwallet.key

If it all works (or you get a possible decrypt) you'll see a Success! message and a recovered.key file. If that file looks like a private key (starts with L or K) with a time stamp then you have successfully obtained your private keys.

Here is an example of the output using the attached Empty-abc23.key file Empty-abc123 key - due to GitHub naming restrictions you may need to rename the attachment by dropping the .log suffix.

Create an example basis.txt containing:

abc
abc1
abc123
abc2

then do the following:

./apply-guesses.sh basis.txt example/Empty-abc123.key                 
Usage: apply-guesses.sh [password CSV] [key file]
Password file: basis.txt
Key file: example/Empty-abc123.key
------
Attempting: abc...
salt=C15B3E24F8F8272F
key=A0C4BD16126D07D9642CCCEADD157A6E959DC3C4382F76D64E8FA86B3DD03C2C
iv =CDFB26AD32EEC6609DFA6DA14641CB45
bad decrypt
4521324204:error:06FFF064:digital envelope routines:CRYPTO_internal:bad decrypt:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-56.60.2/libressl-2.8/crypto/evp/evp_enc.c:521:
Failed
------
------
Attempting: abc1...
salt=C15B3E24F8F8272F
key=73FD5F86503034405E832BEF999D22E5E1E5AAD71CBABE33BB06C3FBD3AB5FE5
iv =7C78469FDD70EC3AD949486ED3D63AF7
bad decrypt
4506599084:error:06FFF064:digital envelope routines:CRYPTO_internal:bad decrypt:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-56.60.2/libressl-2.8/crypto/evp/evp_enc.c:521:
Failed
------
------
Attempting: abc123...
salt=C15B3E24F8F8272F
key=B4B8FC2EBC74A9CF9AFE50DB0C7053E078F1250747DAE984EF33140EC74FA6A1
iv =F6EFF77EE322C7AF068E7D9E742DBB7D
Success!

Examining recovered.key yields L5H4yC6zSPLojPmyCi9hk2T9hNLJqojicmGC7nwS7kck82ARfLuN 2015-04-27T12:58:37Z or similar. The time stamp represents when MultiBit Classic thinks the key was created.

@markburns
Copy link

markburns commented Feb 23, 2021

@gary-rowe fantastically helpful input there. I think I've been down these avenues thoroughly but I'll put aside some time to double check this weekend.

Would you mind also listing the exact version of OpenSSL you are using?

I know that the default parameters changed in between versions. E.g. an older version used the default --md (I think) parameter set to md5 whereas IIRC later ones use SHA256.

@omnivorist
Copy link

@gar-rowe: First, like @markburns, I'd like to thank you for the really helpful and full response you have made to this discussion. I should explain that I spent much of my career developing software in C++ so I have an understanding of computers and software. All the same, I have very little knowledge of encryption, python and these kinds of configuration environments so I am grateful for all the help you can give.

I have read your post very carefully and have a few questions and observations of my own.

I don't understand your first paragraph about Scrypt and the Protobuf serialisation format. Maybe this doesn't apply to my situation. I have a number of .wallet files but I have some .key files also and, so far, I have been concentrating on using these in an attempt to rediscover my (lost) password. The idea then would be to use the password to export the private keys and to import these into a new, supported wallet app. By the way, the version of Multibit I am using is 0.5.17. I loaded the wallet in 2014.

I am using btcrecover (mentioned by other contributors to this post) to try to discover my password.

In order to give myself some confidence, I have created a new (empty) Multibit wallet, and protected it with a password. I then take the .key file associated with this wallet and run btcrecover on it - and btcrecover succeeds in finding the correct password. This suggests that the general approach is sound but I am interested to know if you think my confidence is justified, given the time that has elapsed since I created my first key files.

After reading your post I felt I should try using openssl as you suggest and installed a version on my PC.
Running it on my same test key file with my knwon password gives the following output:

openssl enc -d -p -aes-256-cbc -a -in test.key -out decryptedtest.txt -pass pass:<my_password>
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=D8DEA4286CA2EFD9
key=23DFCC224C109A3F3259FBF1555FD218BF4BA4459A51A5EBA34FD15DFD0F6FA6
iv =C12E27A7E2C3B91FEFE7EFB6A356288F
bad decrypt
12360:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto\evp\evp_enc.c:610:

None of this makes much sense to me. If you feel there is something to be gained by using openssl, I am willing to put the effort in to getting it working but I could use some help.

One more (maybe irrelevant) observation:
I have 3 .key files for the wallet that I am attempting to access:
They are all dated within minutes of each other (Nov 2014) when I first loaded the wallet.
I can't recall the sequence of things that I did at the time but the following is likely:

  1. I created an empty (password protected) wallet
  2. I moved some bitcoin into it
  3. I (may) have changed the password.

The earliest dated key file is only about half the size of the others. Is this what you would expect to see if it corresponded to an empty wallet?

ONCE AGAIN: I really appreciate your help with this

All the best,
David Wilson

@gary-rowe
Copy link
Contributor

gary-rowe commented Feb 23, 2021

@markburns When generating the example file I used the latest version of MultiBit Classic.

The encryption library is com.madgag:sc-light-jdk15on:1.47.0.2 (Spongy Castle) which produces OpenSSL compatible encryption based on a single sound of MD5. More technically, it is PKCS 5 V2.0 Scheme 1 using MD5 with an iteration count of 1. From my review of the git history of the pom.xml this library was in use from 11 June 2012 right up until the final version.

The version of OpenSSL I'm currently using on my test machine is LibreSSL 2.8.3.

I should add that occasionally the script above will report a successful decrypt even when it didn't (Provided AES key is wrong rears again). This version may work better (same rules for print $123 as earlier) also contains the -md md5 flag for newer OpenSSL:

#!/bin/bash
echo Usage: apply-guesses.sh [password CSV] [key file] 
echo Password file: $1
echo Key file: $2
for password in $( awk -F , -v OFS=' ' '{print $123}' $1 ); do
   echo ------
   echo Attempting: $password...
   openssl enc -d -p -md md5 -aes-256-cbc -a -in $2 -out recovered.key -pass pass:$password
   if [ $? -eq 0 ];
     then 
       grep 'T\d\d:\d\d:\d\dZ$' recovered.key
       if [ $? -eq 0 ];
         then 
           echo "Success!";
           break;
         else
           echo "Garbage"
       fi      
     else 
       echo "Failed";
   fi
   echo ------
done

@gary-rowe
Copy link
Contributor

@omnivorist I'll try to answer your questions as best I can

I don't understand your first paragraph about Scrypt and the Protobuf serialisation format. Maybe this doesn't apply to my situation. I have a number of .wallet files but I have some .key files also and, so far, I have been concentrating on using these in an attempt to rediscover my (lost) password. The idea then would be to use the password to export the private keys and to import these into a new, supported wallet app. By the way, the version of Multibit I am using is 0.5.17. I loaded the wallet in 2014.

There are two different mechanisms at play for storing encrypted private keys: the .wallet file (a Protobuf serialisation format) and the .key file (a text based format). The primary storage for MultiBit is the .wallet file and was written to be much more attack resistant than the text file as it would permanently reside on a user's machine. The purpose of the text file was for long term storage of keys away from the user's machines, perhaps on a backup hard drive. This would enable recovery of the private keys using standard tools such as OpenSSL.

It is much faster to test a password against a .key file than a .wallet file. However, sometimes people don't export their private keys so the .wallet is the only choice. Also the .wallet contains verification of the decryption by means of the associated public key, the .key file is much more primitive.

I am using btcrecover (mentioned by other contributors to this post) to try to discover my password.

In order to give myself some confidence, I have created a new (empty) Multibit wallet, and protected it with a password. I then take the .key file associated with this wallet and run btcrecover on it - and btcrecover succeeds in finding the correct password. This suggests that the general approach is sound but I am interested to know if you think my confidence is justified, given the time that has elapsed since I created my first key files.

Yes, that sounds fine. The btcrecover tool is very versatile and a good choice for this kind of thing.

After reading your post I felt I should try using openssl as you suggest and installed a version on my PC.
Running it on my same test key file with my knwon password gives the following output:

openssl enc -d -p -aes-256-cbc -a -in test.key -out decryptedtest.txt -pass pass:<my_password>
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
salt=D8DEA4286CA2EFD9
key=23DFCC224C109A3F3259FBF1555FD218BF4BA4459A51A5EBA34FD15DFD0F6FA6
iv =C12E27A7E2C3B91FEFE7EFB6A356288F
bad decrypt
12360:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto\evp\evp_enc.c:610:

None of this makes much sense to me. If you feel there is something to be gained by using openssl, I am willing to put the effort in to getting it working but I could use some help.

The default hash used to derive keys from a password changed between OpenSSL 1.0.2 and OpenSSL 1.1.0. Try this:

openssl enc -d -p -md md5 -aes-256-cbc -a -in test.key -out decryptedtest.txt -pass pass:<my_password>

One more (maybe irrelevant) observation:
I have 3 .key files for the wallet that I am attempting to access:
They are all dated within minutes of each other (Nov 2014) when I first loaded the wallet.
I can't recall the sequence of things that I did at the time but the following is likely:

I created an empty (password protected) wallet
I moved some bitcoin into it
I (may) have changed the password.

The earliest dated key file is only about half the size of the others. Is this what you would expect to see if it corresponded to an empty wallet?

MultiBit Classic does support using different passwords for the .wallet and .key files. However, when a password is added to a wallet file then an automatic backup of the private keys takes place using the same password. This functionality has been in place since 22 Oct 2012.

@omnivorist
Copy link

Thanks again @gary-rowe.
Lots to think about here but it is reassuring to think that my btcrecover strategy appears sound.
Next step is to get more clever about generating candidate keys and then maybe to run the recovery processes on some sort of 'farm'. I have a bunch of GPUs available (for rendering) but btcrecover doesn't seem capable of exploiting them.

I will carry on but I may not reply for a while. You have given me plenty to think about.
I'll update you when I have news.

@AMDG85
Copy link

AMDG85 commented Feb 25, 2021

I have the same problem:
The password is +95% correct.
----error
"Provided AES key is wrong" ((
http://сергей.бел/img/error.jpg
UPDATE:

Happened! Could pick up through the btcrecover program.
As a result, the password is slightly different!
http://сергей.бел/img/successfully.jpg

If anyone needs help, write.
My site: http://сергей.бел (Russia)
https://t.me/AMDG_SIR

I also have more than 20 mining farms

@constchange
Copy link

@gary-rowe Thanks very much for your responses here. It helped me make real progress in saving the private key. I'm stuck on a new step and really hope you can give some suggestions:

In Dec 2013 I exported a wallet and key file, both encrypted, from multibit classic. Now I only remeber the key password, and have been trying to decrypt it lately.

I installed a multibit classic 0.5.17 from web (now I know this might be dangerous). I set a new wallet, tried to import the encrypted key, and input the password. It didn't say "could not decrypt input string" as in the case I used any other wrong password, but it said "could not understand address in import file". This case was the same as @fl0ppcom once said in this topic.

Then I tried to decrypt it externally; finally found the command openssl enc -d -p -md md5 -aes-256-cbc -a -in test.key -out decryptedtest.txt -pass pass:<my_password> after a lot of searching. The decrypt was successful. Then another problem occur. The plain text it output was like this when opened in notepad:

?躠磱Q?39'ad"t鉼!?狡
_決[�qp嗽雔紧鸘:?A濵彆r闞? &*绉i#唹B7鼞_z?
(modified totally)

I was told in another forum that it looked like a binary file. So I tried to encode it with base64 or base58, imported the result or its substrings from beginning in Electrum, but it seemed none of them were valid address.

I had no idea if it was designed like this in the 2013 version or there was something wrong when the key was exported, and if there is some way to covert that plain text to a private key in common form. Could you tell me something about this?

Thanks and best wishes!

@gary-rowe
Copy link
Contributor

gary-rowe commented Mar 1, 2021

@constchange What you have there is a failed decrypt (similar in nature to the "Provided AES key is wrong" situation). Encryption does not guarantee integrity, only confidentiality. This is why the MultiBit wallet format contains the expected public keys so that the integrity of the private key can be verified after decryption.

To see the actual wallet format, try running the openssl command against the empty demo key export referenced earlier in this thread. Use a password of abc123 and drop the .log suffix.

To verify integrity we can make use of the fact that all encrypted MultiBit private key exports have an ISO-8601 UTC format timestamp (YYYY-MM-DD'T'HH:mm:ss'Z') so that running grep 'T\d\d:\d\d:\d\dZ$' decrypted.txt against your guesses will trigger if it contains what looks like a time formatted string at the end of a line. You can also verify this against the empty demo key export.

@constchange
Copy link

@gary-rowe Thank you for reply!

Yes I have newly exported a few encrypted empty keys from multibit classic 0.5.17 to verify the validity of openssl decryption, and all of them had the same format as the empty abc123 demo key.

(The only strange thing was that the dates of their timestamp are all incorrect, e.g., all in 2014 or 2015 while it is 2021 now. However, they could be decryption successfully and imported to Electrum. So it might be not important.)

So, I wonder the "failed decrypt" you mentioned means that my old key file is alright while I decrypted it with a wrong password and got a wrong plain text occasionally,
or,
the encryption of the old key file failed in 2013, and this key is not integral and totally useless now?

@constchange What you have there is a failed decrypt (similar in nature to the "Provided AES key is wrong" situation). Encryption does not guarantee integrity, only confidentiality. This is why the MultiBit wallet format contains the expected public keys so that the integrity of the private key can be verified after decryption.

To see the actual wallet format, try running the openssl command against the empty demo key export referenced earlier in this thread. Use a password of abc123 and drop the .log suffix.

To verify integrity we can make use of the fact that all encrypted MultiBit private key exports have an ISO-8601 UTC format timestamp (YYYY-MM-DD'T'HH:mm:ss'Z') so that running grep 'T\d\d:\d\d:\d\dZ$' decrypted.txt against your guesses will trigger if it contains what looks like a time formatted string at the end of a line. You can also verify this against the empty demo key export.

@gary-rowe
Copy link
Contributor

@constchange The discrepancy with the timestamp is that it depends on where in the synchronisation process MultiBit was when it exported the keys, and also when it thinks it first saw the key. So the timestamp is just an optimisation rather than an absolute.

During the private key export process, MultiBit Classic would read the file back in to check that it could be decrypted with the given password so it's unlikely that the file was corrupted at that moment, but could have decayed over time. Perhaps a file recovery/repair tool could be used if the original storage device is still available?

@constchange
Copy link

@gary-rowe
Thank you very much! I understand the cases. Pitily the original storage device has been broken...I think I should give up the key file. It seems the only way now is to try to decrypt the wallet file with the tools mentioned in this thread. When I open the wallet file in multibit classic 0.5.17, it shows the correct balance. Does that mean the wallet file is not corrupted and can be decrypted with a correct password?

@gary-rowe
Copy link
Contributor

@constchange You may want to continue working with the exported wallet file as it is much quicker to test a decryption than the .wallet and .wallet.cipher files.

If the .wallet file can be read by MultiBit Classic which appears to be the case then it is very likely to not be corrupted (unless a very specific mangling of bytes within the encrypted section of the private keys has occurred which would be very unlikely). There is a lot of accessible information within a .wallet file which is why it is able to report balance and public keys and so on. It's just the private keys that are encrypted within an overall clear format.

Directly attacking the .wallet file using a dictionary and password fuzzing is one approach, but because (as mentioned earlier) the MultiBit Classic key derivation function is Scrypt then a time constraint is imposed so that decryption takes much longer. If you have confidence in the integrity of the .key file you're going to cover much more ground that way than a direct attack on the .wallet format.

@markburns
Copy link

@markburns When generating the example file I used the latest version of MultiBit Classic.

The encryption library is com.madgag:sc-light-jdk15on:1.47.0.2 (Spongy Castle) which produces OpenSSL compatible encryption based on a single sound of MD5. More technically, it is PKCS 5 V2.0 Scheme 1 using MD5 with an iteration count of 1. From my review of the git history of the pom.xml this library was in use from 11 June 2012 right up until the final version.

The version of OpenSSL I'm currently using on my test machine is LibreSSL 2.8.3.

@gary-rowe me again, having another crack at this.

private static final int NUMBER_OF_ITERATIONS = 1024;

used here:

generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(convertToCharArray(password)), salt, NUMBER_OF_ITERATIONS);

here there is an iteration count of 1024.
quick search doesn't show up anything else:

https://github.com/Multibit-Legacy/multibit/search?q=ITERATIONS&type=code
https://github.com/Multibit-Legacy/multibit/search?q=ITERATION&type=code
https://github.com/Multibit-Legacy/multibit/search?q=iteration&type=code

a grep of the codebase doesn't yield anything further (just in case it's an issue with GH's search)

Where do you get 'iteration count of 1'?

@gary-rowe
Copy link
Contributor

@markburns That's a great investigation, and thanks for taking the time to dig deep into it. You've actually uncovered quite an interesting situation. Before going further, let's recap.

The MultiBit KeyCrypterOpenSSL code was designed so that it would generate output that could be decrypted using the command

openssl enc -d -aes-256-cbc -a -in cipher.txt -out plain.txt -pass pass:aTestPassword

which in 2013 would have meant:

  1. Decrypt using the AES 256 Cipher Block Chaining algorithm
  2. The text provided is in Base64 (UTF-8, 76 characters, new line, padding with =, uses + and /)
  3. Use the default key derivation approach on aTestPassword.

So, OpenSSL back in 2013 had a default Password Based Encryption (PBE) process which was rather weak. It was essentially "combine the password with the salt and perform a single round of MD5 to get the key."

However, in the KeyCrypterOpenSSL code it appears to initialise the key generator with 1024 rounds as seen from this extract:

/**
 * number of times the password & salt are hashed during key creation.
 */
private static final int NUMBER_OF_ITERATIONS = 1024;

...

PBEParametersGenerator generator = new OpenSSLPBEParametersGenerator();

generator.init(
  PBEParametersGenerator.PKCS5PasswordToBytes(convertToCharArray(password)), 
  salt, 
  NUMBER_OF_ITERATIONS);

This is misleading and the source of the confusion.

What is actually happening is the OpenSSLPBEParametersGenerator does not use the NUMBER_OF_ITERATIONS parameter at all. Instead its generateDerivedKey method performs a single MD5 iteration (the ith hash where i=1 call) and then returns the key. There are a few internal loops where the digest is built up but that constitutes a single iteration.

You can check this for yourself by running the KeyCrypterOpenSSLTest and putting a breakpoint against PBEParametersGenerator.getIterationCount() and you'll notice it never gets called and yet the decryption is successful. You'll need to have openssl available on the command line for some of the tests.

I hope this helps, and perhaps offers some relief that previous efforts in decrypting haven't been in vain due to an incorrect number of iterations. If you're able to decrypt the example exported key referenced earlier in this thread using openssl on the command line then you're in good shape to try other passwords on your own files.

@labokho
Copy link

labokho commented Jan 13, 2022

Thanks again @gary-rowe. Lots to think about here but it is reassuring to think that my btcrecover strategy appears smound. Next step is to get more clever about generating candidate keys and then maybe to run the recovery processes on some sort of 'farm'. I have a bunch of GPUs available (for rendering) but btcrecover doesn't seem capable of exploiting them.

I will carry on but I may not reply for a while. You have given me plenty to think about. I'll update you when I have news.

Hello! Some months ago help with multibit.key file to one of my friend. Maybe can also help to you, if you give me little more details. My telegram: https://t.me/labokho

@doge2021
Copy link

doge2021 commented Jan 18, 2022

@gary-rowe Thanks very much for your responses here. It helped me make real progress in saving the private key. I'm stuck on a new step and really hope you can give some suggestions:

In Dec 2013 I exported a wallet and key file, both encrypted, from multibit classic. Now I only remeber the key password, and have been trying to decrypt it lately.

I installed a multibit classic 0.5.17 from web (now I know this might be dangerous). I set a new wallet, tried to import the encrypted key, and input the password. It didn't say "could not decrypt input string" as in the case I used any other wrong password, but it said "could not understand address in import file". This case was the same as @fl0ppcom once said in this topic.

Then I tried to decrypt it externally; finally found the command openssl enc -d -p -md md5 -aes-256-cbc -a -in test.key -out decryptedtest.txt -pass pass:<my_password> after a lot of searching. The decrypt was successful. Then another problem occur. The plain text it output was like this when opened in notepad:

?躠磱Q?39'ad"t鉼!?狡 _決[�qp嗽雔紧鸘:?A濵彆r闞? &*绉i#唹B7鼞_z? (modified totally)

I was told in another forum that it looked like a binary file. So I tried to encode it with base64 or base58, imported the result or its substrings from beginning in Electrum, but it seemed none of them were valid address.

I had no idea if it was designed like this in the 2013 version or there was something wrong when the key was exported, and if there is some way to covert that plain text to a private key in common form. Could you tell me something about this?

Thanks and best wishes!
this is caused by a wrong password or a bug. you can reach
https://www.Btc2doge.com for help

@doge2021
Copy link

doge2021 commented Jan 18, 2022

@clubshaft

I have a serious bug ! import wallet work . I see all my transfers and my saldo ''coins''

when I wanna sent some coins it ask me for password . like it always do now monts from may .

I know my password 100% here is no doubt about it .

I get the error message ► provided AES key is wrong . this is insain ! ! ! why you let me enter a password to my wallet ? not safe without a password you tell to the people . BULLSHIT + 20 BTC my own coins from 2 years pfffffff I can do nothing with it becouse off that stupid password BUG ( scam?? )

Iam now 7 days trying to fix this but nothing work . coincidentally the backup wallet and backup key also give an error . all the other files are ok from my old wallets . they are all there but there is no money on it .

the error message was "NUL" wit the backup key and backup wallet file .

I'm totally misled by multibit WTF I I knew this was going to give problems . no recovery for passwords LOL so that is safe ????? never I read anny messages for warning me becouse the danger off using a password . I know my password let that be clear . more than 23 coins WTF .

████ people if you read this do your password gone before it is to late ! ! just rar the file with password two times or 3 times . up some rar with password in gmail there it stays till we dead . for me it is to late feel verry bad what a massive scam damn ███

obviously, your problem is caused by the bug. can only decrypt the keys manually offline. you can reach https://www.Btc2doge.com

@willcbanks
Copy link

██ peopl

Do you still need recovering your multibit wallet?
I can help you. Telegram: @BitcoinPasswordNet
bitcoinpassword.net

@doge2021
Copy link

doge2021 commented Feb 16, 2023

@clubshaft > Provided AES key is wrong ! I have the key file and ssl is instal now how to run it so I can encrypt like you explane to me

just asked the guy who helped on my wallet, you are correct, the AES is wrong. this is bug of the wallet. not your password problem. but also a small chance is caused by password encryption proocess when you make backup. this is bug. you may reach stephen. www.btc2doge.com wish you succeed.

@doge2021
Copy link

doge2021 commented Oct 7, 2023

@vamosrafa
I also have casually tried BTCrecover, and, more recently a couple hashcat attempts at brute forcing with no luck. Which leads me to believe it might be related to the encryption process itself between the different versions of multbit I used with the keys.

@vamosrafa This is caused by the multibit bug, rather than a password issue. www.btc2doge.com can help this if you still have the files.

@KryptoKicks
Copy link

@markburns were you ever able to derive a password for your .key file. I'm having similar fun so just wondering if you had success or how you achieved that success exactly.

@fl0ppcom
Copy link

fl0ppcom commented Apr 4, 2024

@markburns were you ever able to derive a password for your .key file. I'm having similar fun so just wondering if you had success or how you achieved that success exactly.

I was not ever able to do anything. I have MBC 0.5.17 with full wallet files onboard available (.key, wallet,.cipher)
But nothing provided here is working for me. I have my password stored in excel file and it was easy enough and saved right.
It was my first time to try using a password and in was a mistake to do so ;) Because my wallet was 0 balanced but while I was setting the password someone had sent funds for me on it. So I was not able to receive them ever back since 2013.

And now I read here but have no any idea what to try else. I have tried openssl, tried recovery scripts but nothing works.
So I have only two ideas:

  1. I saved my password but while copy-pasting from the file it had failed and as a result I had some garbage from my clipboard (e.g. some URL or anything else) instead of the written password

  2. A lot of people mention a bug here with MBC - but I still have no idea what the bug is/was and how to solve it
    Becuase if there was a bug - in my mind - MBC had wrongly encrypted data, so nothing like OpenSSL should work right to recover it. Since the mistake is in MBC and it did it in a wrong way, so nothing can do it back except of reverse engineering the bug and trying to recover based on this data ... That what is my thought

But actually everyone who mentioned bug - provide contacts of some suspicious persons (on telegram) or websites (websites are shutdown currently), so I am not sure at all which way to dig further.

P.S. To add some motivation to anyone involved in a past development:

  • I am ready to award anyone who will post a step-by-step bug resolution solution (if it really existed) and BTC address for this award
  • the award will be 1/4 of my wallet value in BTC ( not less than 1 BTC ) - since BTC is clear enough it will be easy to check the %% of the award and wallet value ;)

@omnivorist
Copy link

omnivorist commented Apr 4, 2024 via email

@markburns
Copy link

But actually everyone who mentioned bug - provide contacts of some suspicious persons (on telegram) or websites (websites are shutdown currently), so I am not sure at all which way to dig further.

Very wise to be cautious about people offering help.

I still think it's possible there was a bug. Last time I looked into it there was a missing version from the downloads on the original site. Which would have been the release around the time I had my wallet.

At this point in time though trying to rebuild it all with all the dependencies is like archaeology.

I know one of the original developers has asserted that it's not the case, and that backup and restore works correctly across versions. And without wanting to be disrespectful to him if that is indeed true. It could still be the case that there is a bug and there's also a theoretical chance that it's a well obfuscated one.

Whilst there are unrecovered funds, only the original developers can know the truth. And the chance of multiple people having cosmic rays distort their backups seems in the same realm of unlikely as a nefarious actor concealing a way of locking up people's funds and separately offering the helping hand to unlock them for a fee or to steal.

So whilst it is unknown all possible paths forward seem open. Including fallibility of memory and cosmic rays flipping bits on backups etc.

It would be nice to really draw a line under this one day but if the truth is it's people's memories at fault then I think this thread could carry on endlessly.

Unless someone finds a bug and shares their solution (instead of offering suspicious help privately)

@vamosrafa
Copy link

@gary-rowe attempted to help me but was unsuccessful. Obviously people with BTC locked in a multibit classic wallet are now thinking about cracking the wallet again (myself included).

I still find it strange that quite a few people swear they have the correct password and it does not work, but maybe it is just the case that we want to believe that.

I came across a person in the Bitcoin talk forum who posted back in 2022 saying that Multibit inserted Unicode characters in the password to decrypt the file. The vanupied person has since disappeared.
https://bitcointalk.org/index.php?topic=5307795.0

There is also another person claiming they have figured out some error related to the encryption who seems more doxxed than the people on that forum.
https://pascal-bergeron.com/en/posts/multibit-corrupt-password/

I would like to keep hope alive, it is gut wrenching to see that life chaning amount of money in this old software.

@PascalBergeron1993
Copy link

PascalBergeron1993 commented Apr 10, 2024

I still find it strange that quite a few people swear they have the correct password and it does not work, but maybe it is just the case that we want to believe that. [...] There is also another person claiming they have figured out some error related to the encryption who seems more doxxed than the people on that forum.
https://pascal-bergeron.com/en/posts/multibit-corrupt-password/

From my experience, we humans have terrible memory, so in the vast majority of cases, the user is indeed remembering the wrong password. That being said, I did investigate Multibit's codebase because, well, bugs do happen. And I did find an encoding bug, which is why I wrote my blog post at https://pascal-bergeron.com/en/posts/multibit-corrupt-password/.

To be clear, however: this bug may affect you only if you are trying to decrypt the .key file with a password cracker and if your password contains a character outside the ASCII charset. It shouldn't prevent you from decrypting the .wallet with a password cracker or from decrypting the wallet through Multibit's user interface. In other words, this is a very niche bug.

Still, it proves that bugs do exist within Multibit's codebase, so I hope it will motivate other programmers to inspect it further.

I came across a person in the Bitcoin talk forum who posted back in 2022 saying that Multibit inserted Unicode characters in the password to decrypt the file. The vanupied person has since disappeared.
https://bitcointalk.org/index.php?topic=5307795.0

I have tried to reproduce this bug, to no avail, unfortunately. I will let you know guys if that changes.

@gary-rowe
Copy link
Contributor

gary-rowe commented Apr 12, 2024

I'd just like to add to @PascalBergeron1993's excellent work in identifying an issue with non-ASCII passwords. It does give some hope for fixing some classes of .key file problems.

So what's going on?

If a user enters a non-ASCII password then the most significant byte is dropped leading to a different encryption key than what is expected for the exported .key file only. It is only when the exported .key file needs to be decrypted that problems occur. This occurs because of an ASCII-only conversion routine being used instead of a full UTF-8 so a single Java byte (8-bits) is representing a Java char (16-bits). Please read @PascalBergeron1993's article for a more in-depth review.

Here's a worked example:

  1. Imagine Москва (Cyrillic for Moscow) is your password.
  2. This is represented in Unicode as: 041c 043e 0441 043a 0432 0430 note the 04 in front of each character.
  3. Stripping off the most significant byte (04): 1c 3e 41 3a 32 30 - this is the actual password (sort of >A:20 not Москва).
  4. Notice that 1c is outside of the normal printable ASCII characters (it's a control character called File Separator) and that 3e is the ASCII character > which has special meaning when typed into a terminal/shell.

How did this slip through?

The test cases surrounding this situation in MultiBit Classic didn't pick it up as they didn't fully exercise the end-to-end encryption cycle with openssl - see KeyCrypterOpenSSLTest.java#L253 then compare with KeyCrypterOpenSSLTest.java#L183 As a result, people who used non-ASCII passwords (i.e. non-English characters or those with diacritics) are likely to encounter decryption issue with openssl.

And what can be done?

You'll need a tool that can:

  1. Take a non-ASCII password and remove the most significant byte to simulate MultiBit Classic's bug.
  2. Build a terminal/shell friendly command line for offline use.
  3. Attempt to run openssl using the mangled key and provide some confidence that the .key file has been successfully decrypted.
  4. Be structured in a manner that allows a word list to be fed to it from a wider project.

It's not particularly polished, but here is some code to help others along. It's basic Java that shouldn't need any external libraries. I can't attach it due to GitHub's restrictions on code.

package org.example.bitcoin;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.lang.System.exit;

/**
 * <p>Convert UTF-8 password into openssl command allowing for most significant byte stripping</p>
 * <br/>
 * <h2>Arguments</h2>
 * <ul>
 *   <li>0: Full path to ciphertext file (e.g. example.key)</li>
 *   <li>1: Full path to plaintext file (e.g. example.key.pkain)</li>
 *   <li>2: The password as originally typed (e.g. Москва)</li>
 * </ul>
 * <br/>
 */
public class OpenSSLKeyFixer {

  private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

  // Fast hex formatter from StackOverflow (see https://stackoverflow.com/a/9855338)
  private static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
      int v = bytes[j] & 0xFF;
      hexChars[j * 2] = HEX_ARRAY[v >>> 4];
      hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
    }
    return new String(hexChars);
  }

  public static void main(String[] args) {

    if (args == null || args.length < 3) {
      System.err.println("Arguments: [ciphertext file] [plaintext file] [password]");
      exit(1);
    }

    // Build up an openssl command with higher order byte stripping applied
    StringBuilder cliBuilder = new StringBuilder("openssl enc -d -p -aes-256-cbc -a -md md5 -in \"" + args[0] + "\" -out \"" + args[1] + "\" -pass pass:");
    StringBuilder processBuilder = new StringBuilder("openssl enc -d -p -aes-256-cbc -a -md md5 -in " + args[0] + " -out " + args[1] + " -pass pass:");

    char[] password = args[2].toCharArray();

    // Build up the different versions of the OpenSSL command
    for (char ch : password) {
      byte b = (byte) ch; // Note that MSB will be dropped

      // Restore the potentially mangled char
      char strippedChar = (char) b;

      // Process will correctly handle the input stream
      processBuilder.append(strippedChar);

      // CLI command will need escaping to reliably work in a shell
      if (b < 48 || (b > 57 && b < 65) || (b > 90 && b < 97) || (b > 122 && b < 127)) {
        // Use $(printf '\x00') to print the unprintable
        byte[] bytes = new byte[1];
        bytes[0] = b;
        cliBuilder
          .append("$(printf '\\x")
          .append(bytesToHex(bytes))
          .append("')");
      } else {
        cliBuilder.append(strippedChar);
      }

    }

    // Command built so report to user for use on command line
    String cliCmd = cliBuilder.toString();
    System.out.println(cliCmd);

    Pattern pattern = Pattern.compile("(T\\d\\d:|:\\d\\dZ)");

    // Run local openssl as a process
    try {
      Process p = Runtime.getRuntime().exec(processBuilder.toString());
      p.waitFor();
      if (p.exitValue() != 0) {
        // Read the stderr from the process
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        String line = reader.readLine();
        while (line != null) {
          System.err.println("> " + line);
          line = reader.readLine();
        }
      } else {
        // Read the stdout from the process (as an input)
        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String cmdline = reader.readLine();
        while (cmdline != null) {
          System.out.println("> " + cmdline);
          cmdline = reader.readLine();
        }
        System.out.println("No error reported");
        File deciphered = new File(args[1]);
        if (!deciphered.exists() || !deciphered.isFile()) {
          return;
        }
        List<String> decipheredLines = Files.readAllLines(deciphered.toPath());
        for (String line : decipheredLines) {
          Matcher matcher = pattern.matcher(line);
          if (matcher.find()) {
            // Very likely have a cracked key - slam the brakes on
            exit(0);
          }
        }
      }
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }
}

I'm not a Java programmer how can I run this?

Probably best to ask someone to do it for you, or try the manual approach described later. Don't enter your password into an online tool.

What does the output look like?

The really tricky part here is the creation of a terminal/shell compatible command line that correctly escapes difficult characters. For the Москва to >A:20 example given above, the following has been verified to work:

openssl enc -d -p -aes-256-cbc -a -md md5 -in "/example.key" -out "example.key.plain" -pass pass:$(printf '\x1C')$(printf '\x3E')A$(printf '\x3A')20

Note the use of embedded $(printf ) for single character insertion. The code correctly escapes bash/zsh special characters like >. The use of the Process within Java ensures that no escaping is required but this doesn't work on the command line.

Is there a manual approach?

Yes, the code will do a lot of work for you, but you can do this manually if you're willing to spend a bit of time fiddling with the Unicode character tables

  1. Write out your password on a piece of paper with a bit of space between each character, e.g. Ā b c 1 2 3 (note the first letter is not your standard A)
  2. Refer to the Unicode character tables and work out the code for each character in your password, write it under each one, e.g. 0100 (from Latin Extended-A), 0062 (from Basic Latin), 0063, 0031, 0032, 0033.
  3. Remove the first two digits from the numbers, 00 62 63 31 32 33.
  4. Build the escaped passphrase by replacing CC in this template $(printf \xCC) with your two-digit codes, e.g. $(printf \x00)$(printf \x62)$(printf \x63)$(printf \x31)$(printf \x32)$(printf \x33)
  5. Copy-paste your escaped passphrase to the end of your openssl command as illustrated above.

I can't guarantee that all the above will work but it does go some way to solving a potential issue with MultiBit Classic .key files.

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

No branches or pull requests