Multibit-Legacy / multibit

Deprecated Bitcoin Wallet
https://multibit.org
MIT License
456 stars 393 forks source link

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

Open clubshaft opened 9 years ago

clubshaft commented 9 years ago

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 ███

Mat008 commented 6 years ago

A wrong password which I had (stupidly) forgot and not wrote on a paper.

omnivorist commented 6 years ago

I too have a password issue with Multibit Classic. In my case, it appears to be simply a case of having forgotten the password I set up. Like others I have been using the gurnec tool (seeded with some likely guesses) but with no success so far.

In order to check that the gurnec tool (btcrecover) works I set up a new wallet to try it out on. I changed the password several times on this wallet and each time it dumped a new .key file. These .key files are what you are recommended to use with btcrecover in retrieving the password and indeed it worked perfectly. Running btcrecover on a succession of key files I was able to retrieve the passwords used on each occasion.

When it comes to my REAL wallet - the one containing funds there are three .key files, corresponding, I believe to the point I first created the wallet, when I transferred funds and some other later event (maybe I changed the password). As well as the 'live' wallet I have created wallets corresponding to the earlier .key files. One shows as empty, the other contains the same funds as my current balance.

Apologies for the long preamble but my question is this:

Is it worth applying btcrecover to the other .key files (in case the live one is damaged) ? If so, would I be able to retrieve the funds with the password recovered in that way ?

All insights and observations welcome. I return I will happily share my ongoing experiences in trying to retrieve my lost password

fl0ppcom commented 6 years ago

What is teh procedure "gunrec" you are referring to ?

Where to read about it ?

Thanks.

On Sun, Dec 17, 2017 at 5:21 AM, Mat008 notifications@github.com wrote:

@caroksh https://github.com/caroksh

Like many others, because this specific error message, I thought I was entering the good password, but I was wrong.

Using gurnec tool helped me fing the actual password - so Provided AES key is wrong" error message comes from who knows where...?

I strongly suggest you that you take the time to read and try gunrec procedure. it worked for me.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Multibit-Legacy/multibit/issues/620#issuecomment-352226686, or mute the thread https://github.com/notifications/unsubscribe-auth/Ab7ID4dqcs6a3KMQSd_IAw-YYVeq8Baoks5tBHqegaJpZM4CtmXs .

omnivorist commented 6 years ago

Sorry ... typo on my part. It is gurnec/btcrecover. You can read about it here:

https://github.com/gurnec/btcrecover/blob/master/TUTORIAL.md#running-btcrecover

Interestingly, I'm beginning to think it's that kind of typo (which I am very prone to) that explains why I can't recover my password.

btcrecover appears to be designed to find exactly this kind of problem - but no success so far.

caroksh commented 6 years ago

@Mat008 Thank you for your answer.

I'm also trying with btrecover. Still waiting for the result, it's been running now for more than 2 days and still one more left to finish. I hope it finds my correct password. If not I'll try again with other tokens.

vamosrafa commented 6 years ago

@Mat008 So was it looks like the AES key is wrong in your case was not caused by a correct password and corrupted keys? How close was your actual password you were entering to the correct one?

Also did you get the 94 character output when trying to decrypt it previously?

Mat008 commented 6 years ago

@caroksh The way it worked for me is by trying small token combinations at the time instead of a whole bunch, so the process was faster each time. This way I could get almost instant validation (or not) instead of waiting for too long.

In the token file, I was adding # at each token line head after it was tried and simply adding another line under containing new token(s). This way it was easy to see the combinations I've tried already.

I don't say it is better, but only another way of working.

@vamosrafa I got nothing such as 94 character output (using btcrecover you mean?) Only "password search exhausted."

The actual password was totally different from the one giving the AES error...

caroksh commented 6 years ago

@vamosrafa I have a 44 character output when I use the extract-multibit-privkeys.py file_name.key (from the extract-scripts directory in btcrecover. I copy/pasted it in gedit (sort of notepad but for linux) where you can count the characters, lines, etc... and bytes. But the file_name.key without doing anything to it is 128 characters.

@Mat008 I have also been trying to do it with smaller parts but it's endless so at the end I decided the long way.

Perhaps you can help me with my token: My password has 3 words (all together, just one after the other). I know the first and the last one, but now I am not so sure about the middle one. So I made my token with the following 3 lines in it, except what is in ( ).

This gives me 128508962832 passwords!!!

Do you know of some better or quicker way to do it?

Mat008 commented 6 years ago

Hum... I don't know. Good luck !

markburns commented 6 years ago

Is it possible that the wallets were encrypted/decrypted differently across multibit versions?

I am currently unable to build or find the older versions of multibit to verify. e.g. https://multibit.org/releases/multibit-classic/multibit-0.5.14 https://multibit.org/releases/multibit-classic/multibit-0.5.13 https://multibit.org/releases/multibit-classic/multibit-0.5.12 https://multibit.org/releases/multibit-classic/multibit-0.5.11

don't contain built versions.

Whereas https://multibit.org/releases/multibit-classic/multibit-0.5.15 https://multibit.org/releases/multibit-classic/multibit-0.5.16 https://multibit.org/releases/multibit-classic/multibit-0.5.17 https://multibit.org/releases/multibit-classic/multibit-0.5.18 do.

But this commit looks like a feasible culprit:

https://github.com/Multibit-Legacy/multibit/commit/2d3f9cbcbad330920da0797ec0758fd4b0df5236?diff=split#diff-479841ac9117242ee643ad7c13727b58R260

Which would imply that a (across versions) breaking change may have been introduced with https://multibit.org/releases/multibit-classic/multibit-0.5.18

Unfortunately as I can't build it, I am just resorting to guessing by reading the diff. And I also currently can't even run the downloaded binaries on High Sierra to verify.

Perhaps someone who is not on Mac Os High Sierra can check to see if downloading older versions and unlocking the wallet with those works?

Or perhaps someone with more Java chops than I could build the older versions?

If this seems like a viable avenue to explore, then we might be able to update https://github.com/gurnec/btcrecover to be even more useful

I.e. if it is just a padding difference, and using the same algorithm to decrypt the file as was used to encrypt it is all we need to do, then we can probably update the recovery tool.

Autoband86 commented 6 years ago

@markburns were you able to find version and use 5.15? I have made my wallet in 5.15 and used it since, but had not opened it for quite a while. I am afraid somehow there has been a change in the OS (I have updated a couple of times since I had the wallet), which resulted in the corruption of the files.

markburns commented 6 years ago

@Autoband86 I haven’t investigated any further but I may try in the future on a VM

vamosrafa commented 3 years ago

@markburns did you ever give this a shot? Not sure if you were facing the same issue? At this point it is probably worth it for me to go get a doctorate in cryptography (not that I could) to figure this out haha.

But seriously I can offer a nice bounty (2.5 BTC) if anyone can help me decrypt the key file. I am going to try hashcat in the meantime unless it is a forgotten password.

However some person surfaced on bitcointalk claiming it was an encryption error. If it is hopeless I guess it'd be nice to give up and move on with my life.

https://bitcointalk.org/index.php?topic=5307795.0

gary-rowe commented 3 years ago

Hi @vamosrafa. While I'm no longer involved with the MultiBit project, I would like to help you reach a conclusion for this situation. Drop me an email (see my profile) and I'll see what I can do.

Autoband86 commented 3 years ago

@gary-rowe @vamosrafa I still have the same issue as well and would also be very interested in what you find out. Thank you for a reply.

vamosrafa commented 3 years ago

@Autoband86 have you tried decrypting with any password utilities? I had previously given it to the popular BTC recovery services guy with the password that is giving me the "provided AES key is wrong" with no luck.

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.

markburns commented 3 years ago

I had another look at this over Xmas and whilst I didn't get it building I did look at that specific commit and it doesn't really look at all like a change to the encryption.

@gary-rowe is probably in a better position to comment but whilst the name of the commit refers to a padding fix, it appears to look like a refactor. Just changing the return value to a copy of the bytes. I initially thought it was returning different bytes but I no longer believe that to be the case. So I think that rules out that one case.

I still think there's a possibility for a similar bug in between versions like that though.

There's a lot of file reading and writing goes on, with silent rescuing of exceptions in the codebase. So I still think a complex combination of interactions could have possibly resulted in somehow the files being encrypted differently.

I've also been looking at OpenSSL itself and there are definite difference in default behaviour between versions for that too.

So the command openssl enc -d can take different options to mimic previous versions and result in different encrypted outputs with the default ones. A bit of an aside but it certainly complicated the debug process for me. As there are notes somewhere in a README that refer to this command.

dannydeezy commented 3 years ago

@vamosrafa I'm interested in trying to help if you're still looking

omnivorist commented 3 years ago

APPEAL TO OUR COLLECTIVE EXPERIENCE:

In common with a number of other contributors to this thread I have some bitcoin held in a MultiBit Classic wallet and am unable to export the private key. It is quite possible that I have forgotten my password.

I have used btcrecover (on an earlier occasion) with a huge number of candidate passwords and variations but didn't find my password. Now of course, with the present high value of bitcoin I am tempted to have another try.

I have read through this thread carefully and, as far as I can make out, there were just two success stories:

  1. Someone managed to find their forgotten password using btcrecover
  2. Someone recovered a corrupted key file using recuva.

Beyond those two cases, there is very little evidence of success (or failure).

It would be really helpful if anyone has any knowledge of what has happened to people with password problems on Multibit Classic. Are there other instances of btcrecover working? Are there other cases of corrupted key files? Are there any other approaches worth taking?

Maybe if we pool our knowledge, co-operate and help one another we can all gain.

Incidentally, I console myself with the thought that if I hadn't forgotten my password I would have cashed in years ago and would have lost the chance of the massive gains that are now possible.

gary-rowe commented 3 years ago

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):

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 likehashcat 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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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: *** 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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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.

https://github.com/Multibit-Legacy/multibit/blob/21e2e9d653d291a7dc36d21b6fc14b2a0da48985/src/main/java/org/multibit/crypto/KeyCrypterOpenSSL.java#L64

used here: https://github.com/Multibit-Legacy/multibit/blob/21e2e9d653d291a7dc36d21b6fc14b2a0da48985/src/main/java/org/multibit/crypto/KeyCrypterOpenSSL.java#L128

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 commented 3 years ago

@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 commented 2 years ago

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 commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

██ peopl

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

doge2021 commented 1 year ago

@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 commented 9 months ago

@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 commented 3 months ago

@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 commented 3 months ago

@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:

omnivorist commented 3 months ago

No I never did. One day I will have another try maybe.

On Thu, 4 Apr 2024 at 00:53, KryptoKicks @.***> wrote:

@markburns https://github.com/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.

— Reply to this email directly, view it on GitHub https://github.com/Multibit-Legacy/multibit/issues/620#issuecomment-2035821016, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIIIADPXRFDRIXNB26IFIRDY3SI6TAVCNFSM4AVWMXWKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBTGU4DEMJQGE3A . You are receiving this because you were mentioned.Message ID: @.***>

markburns commented 3 months ago

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 commented 3 months ago

@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 commented 3 months ago

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 commented 2 months ago

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.