MultiBit HDTHE TECHNICAL RECOVERY LIBRARYmail@keychainx.io ↗

MultiBit HD / Technical library

INDEPENDENT KEYCHAINX RESOURCE

Encryption tests: what the fixtures check

The historical test file contains encryption/decryption and password-change tests using test bytes. Inspect the assertions and fixture setup to understand their coverage. The suite is reproduced for reading and has not been executed for this publication.

By KeychainX · 20 September 2026 · Source revision 24a12b199a01

Source inspection only. Historical Java code; not executed or security-audited for this publication.

mbhd-core/src/test/java/org/multibit/hd/core/crypto/EncryptedFileReaderWriterTest.java

View the exact upstream file · Read raw source · License notices

SHA-256: f6e046458af0f7c28cfebcd2786f3fdcde58f365b0e0b07e9452b16f0d3d3556

1package org.multibit.hd.core.crypto;23/**4 * Copyright 2015 multibit.org5 *6 * Licensed under the MIT license (the "License");7 * you may not use this file except in compliance with the License.8 * You may obtain a copy of the License at9 *10 *    http://opensource.org/licenses/mit-license.php11 *12 * Unless required by applicable law or agreed to in writing, software13 * distributed under the License is distributed on an "AS IS" BASIS,14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.15 * See the License for the specific language governing permissions and16 * limitations under the License.17 */1819import com.google.common.collect.Lists;20import org.bitcoinj.utils.BriefLogFormatter;21import org.junit.After;22import org.junit.Before;23import org.junit.Test;24import org.multibit.commons.crypto.AESUtils;25import org.multibit.hd.core.config.Configurations;26import org.multibit.commons.files.SecureFiles;27import org.multibit.hd.core.files.EncryptedContactsFile;28import org.multibit.hd.core.files.EncryptedFileListItem;29import org.multibit.hd.core.files.EncryptedPaymentsFile;30import org.multibit.hd.core.managers.InstallationManager;31import org.multibit.hd.core.services.PersistentContactService;3233import java.io.ByteArrayOutputStream;34import java.io.File;35import java.io.IOException;36import java.io.InputStream;37import java.security.SecureRandom;38import java.util.List;3940import static junit.framework.TestCase.assertTrue;41import static org.fest.assertions.Assertions.assertThat;4243public class EncryptedFileReaderWriterTest {4445  // Nonsense bytes for encryption tests.46  private static final byte[] TEST_BYTES1 = {0, -101, 2, 103, -4, 105, 6, 107, 8, -109, 10, 111, -12, 113, 14, -115, 16, 117, -18, 119, 20, 121, 22, 123, -24, 125, 26, 127, -28, 29, -30, 31};47  private static final byte[] TEST_BYTES2 = {7, -19, 8, 13, -35, 65, 56, 123, 22, -19, 40, 11, -17, 7, 14, -115, 16, 117, -15, 119, 20, 121, 22, 13, -87, 125, 26, 127, -28, 15};48  private static final byte[] CONTACT_BYTES = {10, 104, 10, 36, 55, 100, 49, 57, 49, 49, 51, 49, 45, 102, 99, 99, 57, 45, 52, 55, 51, 51, 45, 97, 55, 55, 49, 45, 49, 98, 99, 57, 102, 55, 97, 50, 52, 48, 51, 55, 18, 4, 65, 110, 110, 97, 26, 16, 97, 110, 110, 97, 64, 107, 101, 101, 112, 107, 101, 121, 46, 99, 111, 109, 34, 0, 42, 34, 49, 80, 82, 81, 87, 122, 115, 105, 55, 84, 116, 101, 80, 56, 120, 50, 97, 109, 114, 114, 90, 111, 118, 81, 52, 113, 56, 106, 116, 110, 102, 81, 121, 72, 50, 0, 58, 0};49  private static final byte[] PAYMENT_BYTES = {10, 86, 10, 34, 49, 72, 90, 112, 57, 107, 99, 103, 66, 118, 78, 116, 105, 102, 117, 75, 100, 110, 52, 113, 99, 89, 85, 117, 122, 88, 80, 100, 112, 76, 85, 87, 71, 71, 18, 0, 24, -96, -115, 6, 34, 31, 10, 6, 48, 46, 54, 51, 52, 53, 18, 3, 85, 83, 68, 26, 8, 66, 105, 116, 115, 116, 97, 109, 112, 34, 6, 54, 51, 52, 46, 53, 48, 42, 0, 48, -124, -111, -101, -84, -5, 42, 56, 0};50  private static final byte[][] TEST_BYTES_ARRAY = new byte[][] {TEST_BYTES1, TEST_BYTES2};5152   private static final CharSequence PASSWORD1 = "aTestPassword";5354  private static final CharSequence PASSWORD2 = "flim flam bim bam jim jam";55  private PersistentContactService contactService;5657  @Before58  public void setUp() throws Exception {5960    InstallationManager.unrestricted = true;61    Configurations.currentConfiguration = Configurations.newDefaultConfiguration();6263    SecureRandom secureRandom = new SecureRandom();6465    // Create a random initialisationVector66    byte[] initialisationVector = new byte[AESUtils.BLOCK_LENGTH];67    secureRandom.nextBytes(initialisationVector);6869    // Create a random key70    secureRandom.nextBytes(initialisationVector);7172    BriefLogFormatter.init();73  }7475  @After76  public void tearDown() throws Exception {7778    InstallationManager.unrestricted = false;7980  }8182  @Test83  public void testEncryptDecryptSuccess() throws Exception {84    // Create a random temporary directory85    File temporaryDirectory = SecureFiles.createTemporaryDirectory();8687    EncryptedPaymentsFile outputFile = new EncryptedPaymentsFile(temporaryDirectory + File.separator + "outputFile.aes");8889    EncryptedFileReaderWriter.encryptAndWrite(PAYMENT_BYTES, PASSWORD1, outputFile);90    InputStream decryptedInputStream = EncryptedFileReaderWriter.readAndDecrypt(91            outputFile,92            PASSWORD193    );9495    assertTrue(outputFile.isValidDecryption(decryptedInputStream));96    decryptedInputStream.close();97  }9899  @Test100  public void testChangeEncryption() throws Exception {101    // Create a random temporary directory102    File temporaryDirectory = SecureFiles.createTemporaryDirectory();103    EncryptedContactsFile contactDbFile = new EncryptedContactsFile(temporaryDirectory.getAbsolutePath() + File.separator + "contacts.aes");104    EncryptedPaymentsFile paymentsFile = new EncryptedPaymentsFile(temporaryDirectory.getAbsolutePath() + File.separator + "payments.aes");105    // Write out the test bytes to the output files106    EncryptedFileReaderWriter.encryptAndWriteDirect(CONTACT_BYTES, PASSWORD1, contactDbFile);107    EncryptedFileReaderWriter.encryptAndWriteDirect(PAYMENT_BYTES, PASSWORD1, paymentsFile);108109    List<EncryptedFileListItem> filesToChange = Lists.newArrayList();110    filesToChange.add(contactDbFile);111    filesToChange.add(paymentsFile);112113    // Change the encryption on the file114    List<EncryptedFileListItem> newFiles = EncryptedFileReaderWriter.changeEncryptionPrepare(filesToChange, PASSWORD1, PASSWORD2);115    EncryptedFileReaderWriter.changeEncryptionCommit(filesToChange, newFiles);116117    int i = 0;118    for (EncryptedFileListItem loopFile : filesToChange) {119      // Read back in and check the encryption120      InputStream decryptedInputStream = EncryptedFileReaderWriter.readAndDecrypt(121              loopFile,122              PASSWORD2123      );124125      assertTrue(loopFile.isValidDecryption(decryptedInputStream));126      decryptedInputStream.close();127128      i++;129    }130  }131132  private byte[] readBytes(InputStream inputStream) throws IOException {133    ByteArrayOutputStream buffer = new ByteArrayOutputStream();134135    int nRead;136    byte[] data = new byte[16384];137138    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {139      buffer.write(data, 0, nRead);140    }141142    buffer.flush();143144    return buffer.toByteArray();145  }146}

Read in context

The historical test file contains encryption/decryption and password-change tests using test bytes. Inspect the assertions and fixture setup to understand their coverage. The suite is reproduced for reading and has not been executed for this publication.

Compare the callers, dependency versions and corresponding tests. The pinned file is one part of a larger application. Do not execute write, prune or migration routines against your only copy of a wallet.

Sources at the reviewed revision