novitski / bitcoinj

Automatically exported from code.google.com/p/bitcoinj
Apache License 2.0
0 stars 0 forks source link

Cannot decrypt an encrypted HD wallet #573

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi Mike,
In MultiBit HD we have a 'Change Password' utility. The test for it started 
failing when I bumped the code to use the latest bitcoinj 0.12-SNAPSHOT.

I've reduced the test to this code below and it still fails:

@Test
  public void testChangePasswordSimple() throws Exception {
    networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET);

    // Create a wallet from a seed
    SeedPhraseGenerator seedGenerator = new Bip39SeedPhraseGenerator();
    byte[] seed1 = seedGenerator.convertToSeed(Bip39SeedPhraseGenerator.split(WalletIdTest.SEED_PHRASE_1));

    long nowInSeconds = Dates.nowInSeconds();

    // Create a wallet using the seed and password
    DeterministicSeed deterministicSeed = new DeterministicSeed(seed1, PASSWORD, nowInSeconds);

    Wallet wallet = Wallet.fromSeed(networkParameters, deterministicSeed);
    wallet.encrypt(PASSWORD);

    assertThat(wallet.checkPassword(PASSWORD)).isTrue();

    // Decrypt the wallet
    wallet.decrypt(PASSWORD);
  }

It fails with the stack trace:

com.google.bitcoin.crypto.KeyCrypterException: Provided AES key is wrong
    at com.google.bitcoin.wallet.DeterministicKeyChain.toDecrypted(DeterministicKeyChain.java:763)
    at com.google.bitcoin.wallet.KeyChainGroup.decrypt(KeyChainGroup.java:577)
    at com.google.bitcoin.core.Wallet.decrypt(Wallet.java:884)
    at org.multibit.hd.core.services.WalletServiceTest.testChangePasswordSimple(WalletServiceTest.java:182)

Original issue reported on code.google.com by jimburto...@gmail.com on 30 Jul 2014 at 3:10

GoogleCodeExporter commented 9 years ago
Does it work if you don't construct the seed yourself? BTW looks like you're 
using custom code for bip39 but I think it shouldn't be necessary?

Original comment by mh.in.en...@gmail.com on 30 Jul 2014 at 3:13

GoogleCodeExporter commented 9 years ago
I'll find a similar test in bitcoinj and do a 'contrast and compare' to see 
what the root cause is

Original comment by jimburto...@gmail.com on 30 Jul 2014 at 3:20

GoogleCodeExporter commented 9 years ago
I have simplified it to use just bitcoinj classes and have it down to:

 public void testChangePasswordSimple() throws Exception {
    String password1 = "";
    String password2 = "1throckSplockChockAdock";

    NetworkParameters networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET);

    long creationTimeSecs = MnemonicCode.BIP39_STANDARDISATION_TIME_SECS;
    String seedStr = "letter advice cage absurd amount doctor acoustic avoid letter advice cage above";

    // Parse as mnemonic code.
    final List<String> split = ImmutableList.copyOf(Splitter.on(" ").omitEmptyStrings().split(seedStr));

    // Test encrypt / decrypt with empty password (password1) - this works ok
    DeterministicSeed seed1 = new DeterministicSeed(split, password1, creationTimeSecs);

    Wallet wallet1 = Wallet.fromSeed(networkParameters, seed1);

    // Encrypt wallet
    wallet1.encrypt(password1);

    // Decrypt the wallet
    wallet1.decrypt(password1);

     // Test encrypt / decrypt with non trivial password (password2) - this fails
    DeterministicSeed seed2 = new DeterministicSeed(split, password2, creationTimeSecs);

    Wallet wallet2 = Wallet.fromSeed(networkParameters, seed2);

    // Encrypt wallet
    wallet2.encrypt(password2);

    // Decrypt the wallet
    wallet2.decrypt(password2);

  }

The wallet2.decrypt fails with the same stack trace, namely:

com.google.bitcoin.crypto.KeyCrypterException: Provided AES key is wrong
    at com.google.bitcoin.wallet.DeterministicKeyChain.toDecrypted(DeterministicKeyChain.java:763)
    at com.google.bitcoin.wallet.KeyChainGroup.decrypt(KeyChainGroup.java:577)
    at com.google.bitcoin.core.Wallet.decrypt(Wallet.java:884)
    at org.multibit.hd.core.services.WalletServiceTest.testChangePasswordSimple(WalletServiceTest.java:204)

On Wed, Jul 30, 2014, at 04:19 PM, Jim wrote:

Original comment by jimburto...@gmail.com on 30 Jul 2014 at 3:40

GoogleCodeExporter commented 9 years ago
I apologize for the lack of clarity.  The BIP32 seed *passphrase* is a 
different animal from the wallet *password*.  For now, please pass an empty 
passphrase to the DeterministicSeed constructor.

Original comment by c1.devra...@niftybox.net on 30 Jul 2014 at 5:16

GoogleCodeExporter commented 9 years ago
Yes - this was it.
Once I changed all my DeterministicSeed constructors to use a blank passphrase 
the tests ran and it works in-real-life too.
Ready to close

Original comment by jimburto...@gmail.com on 30 Jul 2014 at 6:47

GoogleCodeExporter commented 9 years ago

Original comment by mh.in.en...@gmail.com on 3 Aug 2014 at 7:08