Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: pbies on June 25, 2022, 10:47:41 AM



Title: Keyhunter
Post by: pbies on June 25, 2022, 10:47:41 AM
I upgraded keyhunter Python script. See below.

Base58Check encode can be used from library which you should install before running the script with
Code:
pip install base58

Below script is faster than the original one.

Code:
#!/usr/bin/python

import binascii
import os
import hashlib
import sys
import base58

# bytes to read at a time from file (10meg)
readlength=10*1024*1024

magic = '\x01\x30\x82\x01\x13\x02\x01\x01\x04\x20'
magiclen = len(magic)

def b58c(hex):
    return base58.b58encode_check(hex)

def sha256(hex):
    return hashlib.sha256(hex).digest()

def find_keys(filename):
    keys = set()
    with open(filename, "rb") as f:
        # read through target file one block at a time
        while True:
            data = f.read(readlength)
            if not data:
                break

            # look in this block for keys
            pos = 0
            while True:
                # find the magic number
                pos = data.find(magic, pos)
                if pos == -1:
                    break
                key_offset = pos + magiclen
                key_data = "\x80" + data[key_offset:key_offset + 32]
                keys.add(b58c(key_data))
                pos += 1

            # are we at the end of the file?
            if len(data) == readlength:
                # make sure we didn't miss any keys at the end of the block
                f.seek(f.tell() - (32 + magiclen))
    return keys

def main():
    if len(sys.argv) != 2:
        print "./{0} <filename>".format(sys.argv[0])
        exit()

    keys = find_keys(sys.argv[1])
    for key in keys:
        print key

if __name__ == "__main__":
    main()

EDIT:

Taken from original: https://github.com/pierce403/keyhunter

Keyhunter scans files for private keys. You may want to scan HDD image for lost private keys.


Title: Re: Keyhunter
Post by: NotATether on June 25, 2022, 02:13:26 PM
It seems to be in Python 2, which is not supported any more, is very hard to download because the links were hidden by the Python website, and many packages do not work on it anymore.

It should be very trivial to port it to Python 3, no? It should be just replacing things like print statements, unicode strings, and xrange() loops.


Title: Re: Keyhunter
Post by: pbies on June 26, 2022, 10:41:05 AM
It seems to be in Python 2, which is not supported any more, is very hard to download because the links were hidden by the Python website, and many packages do not work on it anymore.

It should be very trivial to port it to Python 3, no? It should be just replacing things like print statements, unicode strings, and xrange() loops.


Done, Python3:

Code:
#!/usr/bin/python3

import binascii
import os
import hashlib
import sys
import base58

# bytes to read at a time from file (10meg)
readlength=10*1024*1024

magic = b'\x01\x30\x82\x01\x13\x02\x01\x01\x04\x20'
magiclen = len(magic)

def b58c(hex):
    return base58.b58encode_check(hex)

def sha256(hex):
    return hashlib.sha256(hex).digest()

def find_keys(filename):
    keys = set()
    with open(filename, "rb") as f:
        # read through target file one block at a time
        while True:
            data = f.read(readlength)
            if not data:
                break

            # look in this block for keys
            pos = 0
            while True:
                # find the magic number
                pos = data.find(magic, pos)
                if pos == -1:
                    break
                key_offset = pos + magiclen
                key_data = b"\x80" + data[key_offset:key_offset + 32]
                keys.add(b58c(key_data))
                pos += 1

            # are we at the end of the file?
            if len(data) == readlength:
                # make sure we didn't miss any keys at the end of the block
                f.seek(f.tell() - (32 + magiclen))
    return keys

def main():
    if len(sys.argv) != 2:
        print("./{0} <filename>".format(sys.argv[0]))
        exit()

    keys = find_keys(sys.argv[1])
    for key in keys:
        print(key)

if __name__ == "__main__":
    main()


Title: Re: Keyhunter
Post by: pbies on June 26, 2022, 03:54:36 PM
And now next version which is giving the keys immediately, as previous version has cached the keys before printing them:

(still Python 3)

Code:
#!/usr/bin/python3

import binascii
import os
import hashlib
import sys
import base58

readlength=10*1024*1024

magic = b'\x01\x30\x82\x01\x13\x02\x01\x01\x04\x20'
magiclen = len(magic)

def b58c(hex):
return base58.b58encode_check(hex)

if len(sys.argv) != 2:
print("./{0} <filename>".format(sys.argv[0]))
exit()

with open(sys.argv[1], "rb") as f:
while True:
data = f.read(readlength)
if not data:
break

pos = 0
while True:
pos = data.find(magic, pos)
if pos == -1:
break
key_offset = pos + magiclen
key_data = b"\x80" + data[key_offset:key_offset + 32]
print(b58c(key_data))
pos += 1

if len(data) == readlength:
f.seek(f.tell() - (32 + magiclen))


Title: Re: Keyhunter
Post by: PrivatePerson on July 13, 2022, 09:14:46 PM
What does this script do?


Title: Re: Keyhunter
Post by: n0nce on July 14, 2022, 12:42:38 AM
What does this script do?
From the name (and the first lines of code that I checked), it may relate to:

keyhunter

A tool to recover lost bitcoin private keys from dead harddrives.

I would advise pbies to confirm and link to the original software so people actually know what it is and what it can do, etc.; also a little benchmark would be great to see by how much it was sped up. ;)


Title: Re: Keyhunter
Post by: NotATether on July 14, 2022, 05:39:44 AM
And now next version which is giving the keys immediately, as previous version has cached the keys before printing them:

A more efficient method would be to cache the keys for only a few seconds (in case more keys are found) before printing them to output and clearing the cache. That way, there is no I/O bottleneck, as printing stuff to the terminal continuously can drastically slow down loops by an order of magnitude.


Title: Re: Keyhunter
Post by: pbies on July 16, 2022, 10:17:38 PM
A more efficient method would be to cache the keys for only a few seconds (in case more keys are found) before printing them to output and clearing the cache. That way, there is no I/O bottleneck, as printing stuff to the terminal continuously can drastically slow down loops by an order of magnitude.

There is no sense to print keys partially. Script is mainly for redirecting to a file (python3 keyhunter.py > keys.txt).


Title: Re: Keyhunter
Post by: PrimeNumber7 on July 16, 2022, 11:00:01 PM
A more efficient method would be to cache the keys for only a few seconds (in case more keys are found) before printing them to output and clearing the cache. That way, there is no I/O bottleneck, as printing stuff to the terminal continuously can drastically slow down loops by an order of magnitude.

There is no sense to print keys partially. Script is mainly for redirecting to a file (python3 keyhunter.py > keys.txt).
It might be better to take a file path as input, and have the script output the keys to that particular file path. If the intended use is for the script to output to a txt file, there shouldn't be the potential for it to output to the console output.


Title: Re: Keyhunter
Post by: pbies on July 17, 2022, 11:16:42 PM
It might be better to take a file path as input, and have the script output the keys to that particular file path. If the intended use is for the script to output to a txt file, there shouldn't be the potential for it to output to the console output.

Input file path and filename are taken.
This is nonsense to always write to a file and put that in code to take output filename always, like you can always redirect the output with > sign.
Now you have two possible options to choose from - print to screen or print to a file.

EDIT:

I am pasting last version from me of keyhunter, it is made to produce WIF + '_0' (space) which is format to directly import to a wallet.

Code:
#!/usr/bin/python3

import binascii
import os
import hashlib
import sys
import base58

readlength=10*1024*1024

magic = b'\x01\x30\x82\x01\x13\x02\x01\x01\x04\x20'
magiclen = len(magic)

def b58c(hex):
return base58.b58encode_check(hex)

if len(sys.argv) != 2:
print("./{0} <filename>".format(sys.argv[0]))
exit()

with open(sys.argv[1], "rb") as f:
while True:
data = f.read(readlength)
if not data:
break

pos = 0
while True:
pos = data.find(magic, pos)
if pos == -1:
break
key_offset = pos + magiclen
key_data = b"\x80" + data[key_offset:key_offset + 32]
print(b58c(key_data).decode('utf-8')+' 0')
pos += 1

if len(data) == readlength:
f.seek(f.tell() - (32 + magiclen))