Bitcoin Forum
November 14, 2024, 08:35:00 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Recovery private keys behind „ckeyA“=“hex: 63 6B 65 79 41“  (Read 406 times)
pischon (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 18


View Profile
June 24, 2020, 08:32:13 PM
Merited by LoyceV (6), joniboini (4), ABCbits (3), OmegaStarScream (2), o_e_l_e_o (2), hugeblack (1)
 #1

Actual situation: some years ago (around 2015) a friend crashed his HDD. After some yeara he asked me to help him to recover the wallet on this HDD. The friend still knows the password for the wallet. I extracted mkey and ckey!. I used pywallet.py (version 2.2 from jackjack) to recover the wallet.dat. Now I investigate that the HDD contains around 100 “ckeyA“=“hex: 63 6B 65 79 41“. As I see the pywallet.py does not use ckeyA to recover the private keys. Script pywallet.py use ckey! to find the private keys (maybe I am wrong). The thread "link" show me that every ckeyA content public and private key. achow101 wrote about that.

Plan: I would like extend the script “pywallet.py” to include the algorithm for ckeyA. Jackjack is unfortunately offline since 2018. The fork from mikeborghi is just a copy from last version from jackjack.

My first questions are:
How is the exact structure behind ckeyA in hex notation? How are the data’s encrypted?

Here are abligatory information:
Bitcoin Client Software and Version Number: Not exactly knows (around beginning of 2015)
Operating System: Windows 7 and Linux (different versions)
System Hardware Specs: Systems with Intel CPU and a lot of diferent HDD. This is not relevant for the problem.
Description of Problem: Recovery private keys behind ckeyA
Any Related Addresses: not relevant
Any Related Transaction IDs: not relevant
Screenshot of the problem: not relevant
Log Files from the Bitcoin Client: not relevant

Thanks a lot in advice!
jackg
Copper Member
Legendary
*
Offline Offline

Activity: 2856
Merit: 3071


https://bit.ly/387FXHi lightning theory


View Profile
June 24, 2020, 08:37:50 PM
 #2

https://github.com/jackjack-jj/pywallet

Jackjacks pywallet code is available here (not me just in case of confusion considering the names) you should be able to extend the recovery code from here if you need to. If you're used to. Programming the git shell is really simple to learn if you're not familiar, github will even give you the clone command to get it in your machine (or you can click to download an archive).

achow101
Moderator
Legendary
*
Offline Offline

Activity: 3542
Merit: 6886


Just writing some code


View Profile WWW
June 24, 2020, 09:40:24 PM
Merited by LoyceV (6), ABCbits (4), joniboini (4), o_e_l_e_o (2)
 #3

Since you are digging into the data that was written to disk, you are going to get a bunch of malformed records due to the way the BDB stores data. There will be partial records and deleted records that were not overwritten.

Instead of trying to look for the keys directly, I would recommend that you try to do file recovery and get the wallet.dat file directly. This is for a few reasons. Firstly, file fragmentation is a thing so you may end up finding chunks of the file and not everything in one place. You may end up finding that a chunk was cutoff. Secondly, it'll be way easier to just load up a wallet.dat file in Bitcoin Core than it will be for me to explain the BDB file format and how Bitcoin Core uses BDB to store data.

When you say "crashed his HDD", what do you mean? How is the HDD damaged? Are you able to load its filesystem? Can you do file recovery on it?

pischon (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 18


View Profile
June 25, 2020, 05:47:59 AM
 #4

Here are more dateails

Description from my friend: He worked with the HDD and linux starts to recover data’s on this HDD. He does not recognize that. After some time he would like open some text files with source code. He was able to open the files, but the content of the files were not more readable. He stopped to work on this HDD and start to recover the wallet. He did not found the wallet. Also the file system is working, but with wrong file table. He had several copies of the same wallet on this HDD. Only one file content needed private key with transaction.

My work on that HDD: As I start to recover the wallet some years later, I did found one wallet with recovery tools. This file was not the right one. After it I used WinHEX to check whole HDD for ckey. I found several places on HDD with ckey (ckey! and ckeyA). As I saw, the recovery tools do not put all the ckey in one file, I tried to found a solution for that. Than I investigate that pywallet.py exist  Grin. I start to work with that script. I was able to create several files with the same mkey and all ckeys. Last week I was count the checked ckeys and saw, that ckeyA are not used by pywallet.py.

Conclusion:
-   Correct mkey is present
-   Password is present
-   All ckey! are already checked
-   ckeyA are present, but not checked
achow101
Moderator
Legendary
*
Offline Offline

Activity: 3542
Merit: 6886


Just writing some code


View Profile WWW
June 25, 2020, 03:50:31 PM
Merited by ABCbits (1), hugeblack (1), A-Bolt (1)
 #5

How are you determining that ckeyA isn't being checked? I've looked through the pywallet source and it doesn't distinguish between ckey! and ckeyA. It just looks for ckey.

Note that the actual prefix for encrypted keys is just ckey. The ! and A are there because the ckey prefix is followed immediately by the length of the public key and then the public key itself. The hex for ! is 0x21 which is also the length of a compressed public key. The hex for A is 0x41 which is the length of an uncompressed public key.

pischon (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 18


View Profile
June 25, 2020, 08:39:39 PM
 #6

I created two files. One file with real ckey! and ckeyA. Second file is a copy from the first file without ckey!.

First file was created to check, that the wallet will be recognized. The second file is created to prove the algorithm second time.

In both cases the script pywallet.py does not recognize ckeyA.
pischon (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 18


View Profile
June 27, 2020, 08:13:03 PM
 #7

Before I start to extend the code of pywallet.py. I need some support from this forum.
My first step is to understand the data structure behind ckeyA.

Example as HEX values:
47000104636B65794104500E6D9173EDF9C623461F23BF27A9CDF74B011C75D348364FDEC49605F D8A14E896DEBFC0BF189D55D5A38B861A506BDE3E2AEB7D481DC1FE0116251AFB906F8286310001 3092F0D25C86D3259732547660F985AB36CF8A4BB6C1815DA2AB990DF9F7F1B3993C9553E028257 676C85189177C311E16

How I understand the structure until now:
<47000104636B657941> <preamble ckeyA (9 Byte)>
<04500E6D9173EDF9> < public key signature (8 Byte)>
<C623461F23BF27A9CDF74B011C75D348364FDEC49605FD8A14E896DEBFC0BF189D> <uncompressed public key (33 Byte)> <55D5A38B861A506BDE3E2AEB7D481DC1FE0116251AFB906F82863100013092F0D25C86D32597325 47660F985AB36> <”something” + private key signature (46 Byte)> <CF8A4BB6C1815DA2AB990DF9F7F1B3993C9553E028257676C85189177C311E16> <uncompressed private key (32 Byte)>

Do I split correct the bytes? The area “something + private key signature” is for me a black box up-to-now.

Thank you!

achow101
Moderator
Legendary
*
Offline Offline

Activity: 3542
Merit: 6886


Just writing some code


View Profile WWW
June 27, 2020, 10:03:30 PM
Merited by joniboini (4), ABCbits (2)
 #8

No. There is no "public key signature" or "private key signature", whatever those mean.

ckeyA is not a distinct record from ckey!. As I said earlier, they are the same ckey record, the last character is just the ascii interpretation of a byte indicating the length of the public key.

The format of a ckey key record is:

Code:
<length of id string > | ckey | <length> | <public key>

The value record is stored separately in the BDB database file. There may be junk between the ckey key and the ckey value. They may not be stored next to each other either

The ckey value record is:
Code:
<length of private key> | <private key> | <sha256 of private key>

Note that the pipe character (|) denotes concatenation.

ckeyA is really ckey | 0x41, which means that the length of the public key is 0x41 bytes, i.e. 65 bytes. This means the public key is uncompressed. The <length of id string> will be 4 for ckey.

Private keys are 48 bytes in length which means that you will see a length byte of 0x30. The checksum may or may not be there as it was an optimization added later.

Each record also be prepended by a length of the full record. This length is added by BDB.

pischon (OP)
Newbie
*
Offline Offline

Activity: 5
Merit: 18


View Profile
June 29, 2020, 12:10:13 PM
Last edit: June 29, 2020, 12:20:41 PM by pischon
 #9

achow101, thanks for this feedback!

Because of your feedback I did found more as 600 private keys on HDD because of preamble „0x3081d30201010420” (compressed) and “0x308201130201010420” (not compressed).

As I know the public key is generated over private key (One of thousand examples: https://www.crypto-lyon.fr/how-to-get-an-address-from-a-private-key-on-bitcoin.html).

Now my next doubt: If no public key is found (mkey and private keys are present), then the script stops the recovery. Please start to see with the line 1463 in pywallet.py Version 2.2. Why the script pywallet.py try to find mkey, public keys but not private keys as first? Is here some hidden logic?  Huh
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!