Author

Topic: Retrieve extended private key from child keys or sibling keys Asked today Modifi (Read 224 times)

newbie
Activity: 4
Merit: 0
I retrieved the Xpriv from these two masterkeys and it gives me the wallet addresses. This wallet also contains mkey encrypted which decrypts well with my password.

The wallet.dat that interests me contains 4 derivation masterkey ( m). The first two are that of wallet.{timestamp}.bak. The masterkey encrypts mkey, salt, nderiv are the same as wallet.{timestamp}.bak.

But on the wallet.dat the masterkey does not decode the ckeys. It gives me different addresses when I use the masterkey. But its decrypt all the same adress than wallet.{timestamp}.bak.

I found in the wallet.dat unencrypted addresses.
I don't know how it is possible that the wallet.bak data is in my new wallet.dat and that the masterkey does not decrypt all the keys.

In summary it is as if the decryption keys of the wallet.dat are that of wallet.{timestamp}.bak. As if the mkey has been replaced by bitcoin core by the old wallet.

So you seem to already know the password and also have a backup wallet.dat.

This seems to imply that Bitcoin Core has encrypted some of the mkeys with intermediate key at the time of crash. The question is, how is this key generated, and is the process even deterministic from the password?

This is what it seems to me, do you think that the encrypted mkey which encrypts the other addresses is represented with the salt and the nderiv in the wallet.dat, I can find a regular expression in order to scan all the possibilities and test them. Below is the code that is used to encrypt the wallet

Code:
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{
    if (IsCrypted())
        return false;

    CKeyingMaterial _vMasterKey;

    _vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
    GetStrongRandBytes(&_vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);

    CMasterKey kMasterKey;

    kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
    GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);

    CCrypter crypter;
    int64_t nStartTime = GetTimeMillis();
    crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
    kMasterKey.nDeriveIterations = static_cast(2500000 / ((double)(GetTimeMillis() - nStartTime)));

    nStartTime = GetTimeMillis();
    crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
    kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast(kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;

    if (kMasterKey.nDeriveIterations < 25000)
        kMasterKey.nDeriveIterations = 25000;

    WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);

    if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
        return false;
    if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey))
        return false;

    {
        LOCK(cs_wallet);
        mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
        assert(!encrypted_batch);
        encrypted_batch = new WalletBatch(*database);
        if (!encrypted_batch->TxnBegin()) {
            delete encrypted_batch;
            encrypted_batch = nullptr;
            return false;
        }
        encrypted_batch->WriteMasterKey(nMasterKeyMaxID, kMasterKey);

        if (!EncryptKeys(_vMasterKey))
        {
            encrypted_batch->TxnAbort();
            delete encrypted_batch;
            encrypted_batch = nullptr;
            // We now probably have half of our keys encrypted in memory, and half not...
            // die and let the user reload the unencrypted wallet.
            assert(false);
        }

        // Encryption was introduced in version 0.4.0
        SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch, true);

        if (!encrypted_batch->TxnCommit()) {
            delete encrypted_batch;
            encrypted_batch = nullptr;
            // We now have keys encrypted in memory, but not on disk...
            // die to avoid confusion and let the user reload the unencrypted wallet.
            assert(false);
        }

        delete encrypted_batch;
        encrypted_batch = nullptr;

        Lock();
        Unlock(strWalletPassphrase);

        // if we are using HD, replace the HD seed with a new one
        if (IsHDEnabled()) {
            SetHDSeed(GenerateNewSeed());
        }

        NewKeyPool();
        Lock();

        // Need to completely rewrite the wallet file; if we don't, bdb might keep
        // bits of the unencrypted private key in slack space in the database file.
        database->Rewrite();

        // BDB seems to have a bad habit of writing old data into
        // slack space in .dat files; that is bad if the old data is
        // unencrypted private keys. So:
        database->ReloadDbEnv();

    }
    NotifyStatusChanged(this);

    return true;
}
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
I retrieved the Xpriv from these two masterkeys and it gives me the wallet addresses. This wallet also contains mkey encrypted which decrypts well with my password.

The wallet.dat that interests me contains 4 derivation masterkey ( m). The first two are that of wallet.{timestamp}.bak. The masterkey encrypts mkey, salt, nderiv are the same as wallet.{timestamp}.bak.

But on the wallet.dat the masterkey does not decode the ckeys. It gives me different addresses when I use the masterkey. But its decrypt all the same adress than wallet.{timestamp}.bak.

I found in the wallet.dat unencrypted addresses.
I don't know how it is possible that the wallet.bak data is in my new wallet.dat and that the masterkey does not decrypt all the keys.

In summary it is as if the decryption keys of the wallet.dat are that of wallet.{timestamp}.bak. As if the mkey has been replaced by bitcoin core by the old wallet.

So you seem to already know the password and also have a backup wallet.dat.

This seems to imply that Bitcoin Core has encrypted some of the mkeys with intermediate key at the time of crash. The question is, how is this key generated, and is the process even deterministic from the password?
newbie
Activity: 4
Merit: 0
Hi maybe check help here: https://bitaps.com/bip32.  This site can help you find other addresses. I would run this offline then check run,  You can send me generous reward if you find.

Yes I have already done it but as I only have access to two xpriv out of the 4, it does not decode the keys that interest me
newbie
Activity: 4
Merit: 0
I lost access to my wallet since calling *encryptwallet* which crashed the bitcoin software.
My wallet contains 4 masterkeys
As far as I know bitcoin core (that has encryptwallet command) creates wallets that only contain a single master key not multiple ones.
Are you confusing child private keys with master keys or is it not even a bitcoin core wallet file?

It also makes no sense that only part of the keys were decrypted and not all of them from the same wallet. Are you sure this wallet is not "modified" manually by someone?

- Is there a way to convert the public key like I did for the private key?
 - Can I find the sibling keys with the amount of private keys that I have recovered?
 - Do you see another way to recover my funds?
No, you'll need to find the master key that derives all of this and then simply derive all the child keys instead of trying to find them one by one.
Also any decryption method that you used for one of them and worked, should work on all of them if the wallet file is not manipulated.

The masterkeys I'm talking are there original derivation like m/0'/0'/0' or the masterkey I'm talking about is m.

I have two wallets in the folder, a wallet.{timestamp}.bak and a wallet.dat

The wallet.{timestamp}.bak contains two bip32 masterkey for derivation.

I retrieved the Xpriv from these two masterkeys and it gives me the wallet addresses. This wallet also contains mkey encrypted which decrypts well with my password.

The wallet.dat that interests me contains 4 derivation masterkey ( m). The first two are that of wallet.{timestamp}.bak. The masterkey encrypts mkey, salt, nderiv are the same as wallet.{timestamp}.bak.

But on the wallet.dat the masterkey does not decode the ckeys. It gives me different addresses when I use the masterkey. But its decrypt all the same adress than wallet.{timestamp}.bak.

I found in the wallet.dat unencrypted addresses.
I don't know how it is possible that the wallet.bak data is in my new wallet.dat and that the masterkey does not decrypt all the keys.

In summary it is as if the decryption keys of the wallet.dat are that of wallet.{timestamp}.bak. As if the mkey has been replaced by bitcoin core by the old wallet.

Regarding the reward and that I have been trying to solve the problem for 1 year, the reward is 0.3 BTC.

I created an edit in the post where I relate the last test and result
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
Hi maybe check help here: https://bitaps.com/bip32.  This site can help you find other addresses. I would run this offline then check run,  You can send me generous reward if you find.

That's not going to help the OP because they cannot even decode their master public key, which is required to derive addresses in the first place.
newbie
Activity: 28
Merit: 0
 Hi maybe check help here: https://bitaps.com/bip32.  This site can help you find other addresses. I would run this offline then check run,  You can send me generous reward if you find.
legendary
Activity: 3472
Merit: 10611
I lost access to my wallet since calling *encryptwallet* which crashed the bitcoin software.
My wallet contains 4 masterkeys
As far as I know bitcoin core (that has encryptwallet command) creates wallets that only contain a single master key not multiple ones.
Are you confusing child private keys with master keys or is it not even a bitcoin core wallet file?

It also makes no sense that only part of the keys were decrypted and not all of them from the same wallet. Are you sure this wallet is not "modified" manually by someone?

- Is there a way to convert the public key like I did for the private key?
 - Can I find the sibling keys with the amount of private keys that I have recovered?
 - Do you see another way to recover my funds?
No, you'll need to find the master key that derives all of this and then simply derive all the child keys instead of trying to find them one by one.
Also any decryption method that you used for one of them and worked, should work on all of them if the wallet file is not manipulated.
copper member
Activity: 2856
Merit: 3071
https://bit.ly/387FXHi lightning theory
Do you know what keys belong to which nmemonics? I'm not sure if it's possible but I'd assume if you'd be able to link 2 private keys somehow as coming from the same xpub then you'd be able to calculate the further on.

It's normally suggested an xpub and a private key are usually what's needed to make a master private key though so I don't know how you'd go about doing thst any further.

You might just have to try to search harder/hope you've made another backup.
newbie
Activity: 4
Merit: 0
Hello,

I've looked through the various questions and answers regarding this topic but I can't find the answers to mine.

I lost access to my wallet since calling *encryptwallet* which crashed the bitcoin software.
I did many scans with all the tools available on github and also some that I wrote.

My wallet contains 4 masterkeys (**m path**) of which 2 can be decrypted with the password of the wallet and contains more than 1500 addresses. Only around 200 can be decrypted with the password.


I found the xpriv for these two decrypted masterkeys by importing them into bitcoin core with the *sethdseed* function.

I found in the hexadecimal chains of the portfolio 20 addresses which have not been encrypted and of which I therefore know the private key, the encrypted key, the pub key, the derivation.


I can't find any way to find the xpub of the other two mastrkeys which will have allowed me to find all the other private keys. The Chaincode is missing and can't find it in wallet.dat.

I tried to modify the Bitcoin code to convert according to the same logic as for the WIF key import but without success.

My questions are:

 - Is there a way to convert the public key like I did for the private key?
 - Can I find the sibling keys with the amount of private keys that I have recovered?
 - Do you see another way to recover my funds?

I anticipate a generous reward.
Thank You

EDIT :
Bitcoin core uses reinforced derivation, it is impossible to find the related private key with a child private key and the xpub.

I did a scan of the wallet and there is no non-encrypted masterkey that interests me.

Finding the key from the IV and cipher and plain text is not possible in AES-256-CBC.

None of the non-crypt keys I found match the xpriv or masterkey (m)

In the debug.log I was told that the nderivation is 65277, but pywallet reports 151678. I tried all the possibilities and it did not work, the masterkey crpyter and the salt are not the good ones
Jump to: