Yes, Multibit Classic Does Corrupt the Password in Some Cases

Multibit Classic is a Bitcoin wallet that was popular during the 2010s, but that was abandoned in 2017. Nowadays, some people are trying to move their Bitcoins out of their wallet, but they can’t because their password is being rejected. Yet, they swear that it is correct and that their password must have been corrupted somehow.

I decided to investigate these claims and found out that Multibit Classic does, in some cases, corrupt the password meant to protect the wallet. In this article, I will explain my discovery further. Note that this text is technical by nature and is intended for readers with programming knowledge, especially in regard to character encoding. Bytes are written in hexadecimal format.

Who is affected by this issue?

This issue may affect users who are using password crackers – like hashcat, John the Ripper or BTCRecover – to decrypt the .key file associated to their wallet. It is more likely to affect them if their password contains characters undefined in the ASCII charset.

This issue should not affect users who are using password crackers on their .wallet file. Some of these tools have their own problems when it comes to character encoding, but they are unrelated to the issue described in this article.

This issue should not affect users who are attempting to unlock their wallet directly through Multibit Classic.

How was this issue reproduced?

This issue was reproduced within the following environment:

  • Multibit Classic version 0.5.14.
  • Java Runtime Environment version 8 update 231.
  • Windows 10 Home build 19044.2846.

The problem method: PKCS5PasswordToBytes

When you choose your password through Multibit’s user interface, the software passes it as an argument to the PKCS5PasswordToBytes method, which is part of the Spongy Castle library. This method accepts the password as a char array and outputs it as a byte array. It is later used to either encrypt or decrypt a .key file. Below, here’s how the method is implemented in the PBEParametersGenerator.java file. Can you spot the bug?

 1public static byte[] PKCS5PasswordToBytes(
 2    char[]  password)
 3{
 4    byte[]  bytes = new byte[password.length];
 5
 6    for (int i = 0; i != bytes.length; i++)
 7    {
 8        bytes[i] = (byte)password[i];
 9    }
10
11    return bytes;
12}

In Java, the char type is made up of 2 bytes; however, the code above assumes that a char is made up of only one byte! Thus, for each char processed in the loop, the low-order byte is kept while the high-order byte is discarded. Under the right circumstances, this can become an issue.

When everything goes well

As an example, let’s say that our password is made up of a single letter:

t

Below, here’s a table listing the encoding of this password for some of the most popular charsets.

Charset Encoding
ASCII 74
ISO-8859-1 74
CP-1251 74
CP-1252 74
UTF-8 74
UTF-16 BE 00 74
UTF-16 LE 74 00
UTF-32 BE 00 00 00 74
UTF-32 LE 74 00 00 00

Since Java relies on the UTF-16 BE charset, Multibit encodes the password as 00 74 when it is entered in the user interface. When it is converted through the PKCS5PasswordToBytes method, the high-order byte (00) is dropped whereas the low-order byte (74) is kept.

While Multibit’s conversion routine is incorrect, the end result is not in this case. Indeed, 74 is the proper encoding for our password in ASCII, ISO-8859-1, CP-1251, CP-1252 and UTF-8. Thus, a password cracker should be able to decrypt the .key file as long as one of the aforementioned charsets is used.

When things don’t go so well

Now, let’s say that our password is made up of a single character, the euro symbol:

Below, here’s a table listing the encoding of this password for some of the most popular charsets.

Charset Encoding
ASCII N/A
ISO-8859-1 N/A
CP-1251 88
CP-1252 80
UTF-8 E2 82 AC
UTF-16 BE 20 AC
UTF-16 LE AC 20
UTF-32 BE 00 00 20 AC
UTF-32 LE AC 20 00 00

Since Java relies on the UTF-16 BE charset, Multibit encodes the password as 20 AC when it is entered in the user interface. When it is converted through the PKCS5PasswordToBytes method, the high-order byte (20) is dropped whereas the low-order byte (AC) is kept.

Unlike with our previous example, AC is not the proper encoding for our password in any of the charsets above. As such, a password cracker may fail to decrypt the .key file even with the correct password.

What are your options?

If you haven’t done so already, you should try to unlock your wallet through Multibit Classic directly. You can download a working copy of the software by clicking here. Unfortunately, this approach quickly becomes impractical if you are unsure of your password and must type in every guess. In such a case, you will need a password cracker.

You can avoid the bug described in this article by using the password cracker on a .wallet file instead of a .key file. While this approach beats typing in every guess, it scales terribly as the .wallet file has much better protection against password crackers than the .key file. Moreover, some of these tools have their own set of character encoding issues you should be aware of.

If you use the password cracker on a .key file, they are multiple workarounds for character encoding issues, but they should be evaluated on a case-by-case basis and it is outside the scope of this article. I encourage you to keep doing your research or to contact me.

Conclusion: don’t lose hope!

Back in the 2010s, many people bought Bitcoins when its price was very low – at least, compared to today – and they trusted Multibit Classic to store their assets. Unfortunately, some of them are now unable to access their wealth because their password is being rejected. The bug described in this article may only explain a handful of cases, but I hope that the information presented here will be useful to you.