Automatisieren Sie die Bip39-Seed-Wiederherstellung

Ich wurde kürzlich aus meinem Ledger NanoS ausgesperrt, als ich den PIN-Code vergessen habe. Als ich versuchte, meinen Wiederherstellungssatz zurückzusetzen, stellte ich fest, dass ich nur 23 der 24 erforderlichen Wörter habe (ich bin mir leider nicht sicher, wie es passiert ist). Ich bin mir nicht sicher, in welcher Position sich das Wort befindet, aber ich bin mir sicher, dass die Reihenfolge der anderen 23 Wörter korrekt ist. Davon abgesehen muss ich alle Möglichkeiten auf jeder anderen Position ausprobieren.

Ich habe diesen Beitrag gefunden, der mir eine Liste von Wörtern gibt, um das fehlende Wort zu füllen: Ich habe meine Bitcoin-Wallet verloren und habe nur 11 von 12 mnemonischen Seed-Phrase-Wörtern. Wie bekomme ich meine Bitcoins?

Ich suche nach einem Stück Code, mit dem ich die Lösungen ändern kann, ohne die Brieftaschen 1 nach 1 manuell auszuprobieren.

Benötigen Sie ein Programm, um alle möglichen Kombinationen zu generieren? ein Beispiel für ein Programm, das alle möglichen Kombinationen in der Datei speichert. Oder suchen Sie ein Programm zum Testen aller möglichen Kombinationen direkt auf Dispositiv?
Ich habe jetzt alle Möglichkeiten durch den Code auf dem Link des ursprünglichen Beitrags aufgelistet. Ich möchte nur eine automatisierte Möglichkeit haben, die Liste mit etwa 200 Einträgen zu testen (ich glaube, die Liste ist aufgrund der Prüfsummenregel so klein). Ich habe Electrum Wallet heruntergeladen und einige manuell getestet, aber der Prozess ist ziemlich mühsam

Antworten (3)

Kennen Sie eine der Adressen im Schlüsselbund? Ledger verwendet die BIP44-Ableitung, sodass Sie eine Schleife schreiben können, um verschiedene Seed-Phrasen zu überprüfen und die resultierenden Adressen mit einer Adresse zu vergleichen, von der Sie wissen, dass sie im Schlüsselbund enthalten sein sollte. Auf diese Weise können Sie Ihre Wiederherstellungswörter eingeben, ohne online sein zu müssen.

Wenn ich es wäre, würde ich zum Beispiel wahrscheinlich etwas mit der bitcoinjs-lib schreiben . Hier ist ein Anfang, der mit BitcoinJs geschrieben wurde (HINWEIS, ich verwende Version 3.3.2). Dies nimmt einen Wiederherstellungs-Seed und eine Adresse und durchsucht den Schlüsselbund und teilt Ihnen mit, ob die Adresse darin vorhanden ist oder nicht.

//var words = "segment increase inch ensure corn cigar suggest fetch output proof peasant enact";
//var addr = "1c4XzQx7Uh8CnxzAN5CRrUjkbxGB1GUWp";

var searchbtn = document.getElementById("searchbtn");
searchbtn.onclick = function(){

    var words = document.getElementById("words").value;
    var addr = document.getElementById("addr").value;
    var depth = document.getElementById("depth").value;
    inkeychain(addr, words, depth);
}


function inkeychain(addr, keychain, depth){
    var isfound = false;
    for(var i=0;i<depth;i++){
        var seed = hd.bip39.mnemonicToSeed(keychain);
        var root = b.bitcoin.HDNode.fromSeedBuffer(seed)
        //const root = bitcoin.HDNode.fromSeedHex(seed.toString('hex'))
        var wallet = root.derivePath("m/44'/0'/0'/0/"+i);

        //legacy
        var address = wallet.getAddress();
        var wif = wallet.keyPair.toWIF();

        //segwit p2sh
        var pubKey = wallet.keyPair.getPublicKeyBuffer();
        var pubKeyHash = b.bitcoin.crypto.hash160(pubKey);
        var redeemScript = b.bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash);
        var redeemScriptHash = b.bitcoin.crypto.hash160(redeemScript);
        var scriptPubKey2 = b.bitcoin.script.scriptHash.output.encode(redeemScriptHash);
        var p2shsegwit = b.bitcoin.address.fromOutputScript(scriptPubKey2);

        if(address===addr){
        isfound = true;
            console.log(address, wif);
            $('#result').html('Found '+addr+' in this keychain at '+i+' position in the keychain');
            alert('Found!');
        } else if (p2shsegwit===addr){
            //check for segwit p2sh
            isfound = true; 
            console.log(p2shsegwit, wif);
            $('#result').html('Found '+addr+' in this keychain at '+i+' position in the keychain');
            alert('Found!');
        } 
    }
if(isfound===false){
    $('#result').html('No matches');
}

}

https://bitcoinfunction.com/?id=5d9ea508d9bed

Von hier aus könnten Sie noch einen Schritt weiter gehen und die wordsVariable zu einem Array mit all Ihren verschiedenen Kombinationen machen und sie dann alle durchschleifen.

Ich kenne nur 23 der 24 Wörter und habe tatsächlich gerade die Transaktionsaufzeichnung gefunden, in der ich die Bitcoin von einer anderen Brieftasche in die Ledger Nano s verschoben habe. Würde Ihre Methode in diesem Fall funktionieren? Auch wenn ich Wortsätze in Elektron manuell teste und m/84'/0'/0' anstelle von m/44'/0'/0' auswähle, würde es mir zeigen, ob sich Münzen in der Brieftasche befinden oder nicht? Ich bin ein bisschen Computer-versiert, aber einiges davon übersteigt meinen Kopf, also entschuldigen Sie die scheinbar dummen Fragen.

Wenn Sie diese Antwort (mithilfe von Python) aus der verwandten Frage erweitern , mit der Sie verknüpft sind, können wir damit beginnen, die Liste der Möglichkeiten einzugrenzen.

Beginnen Sie mit Ihrer geordneten Liste bekannter Wörter:

ordered_known_words = [
    'glory',
    'twice',
    'film',
    'near',
    'senior',
    'trust',
    'thunder',
    'endorse',
    'suggest',
    'scheme',
    'habit',
    'limit',
    'slow',
    'yard',
    'clog',
    'attend',
    'axis',
    'enough',
    'only',
    'magic',
    'hair',
    'rule',
    'zone',
]

Generieren Sie zunächst ein Phrasenmuster für jede mögliche Position Ihres fehlenden Wortes:

def generate_phrase_patterns(ordered_known_words, mnemonic_length=24):
    list_of_patterns = []

    for i in range(0, mnemonic_length):
        list_template = ['{x}'] * mnemonic_length
        word_position = 0

        for position, known_word in enumerate(ordered_known_words):
            if i <= position:
                list_template[position + 1] = known_word
            else:
                list_template[position] = known_word
            word_position += 1

        list_of_patterns.append(', '.join(list_template))

    return list_of_patterns

Dies ergibt eine Liste von Listen in etwa wie folgt:

{x}, glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, {x}, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, {x}, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, {x}, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, {x}, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, {x}, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, {x}, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, {x}, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, {x}, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, {x}, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, {x}, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, {x}, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, {x}, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, {x}, yard, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, {x}, clog, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, {x}, attend, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, {x}, axis, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, {x}, enough, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, {x}, only, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, {x}, magic, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, {x}, hair, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, {x}, rule, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, {x}, zone
glory, twice, film, near, senior, trust, thunder, endorse, suggest, scheme, habit, limit, slow, yard, clog, attend, axis, enough, only, magic, hair, rule, zone, {x}

Fügen Sie dies nun in den Code aus dieser Antwort auf die verwandte Frage ein, die Sie verlinkt haben, um eine Liste aller möglichen Phrasen zu erstellen:

def generate_all_valid_phrases(phrase_patterns):
    from btctools.HD import check, WORDS
    total_phrases = []
    for pattern in phrase_patterns:
        for word in WORDS:
            mnemonic = pattern.format(x=word)
            if check(mnemonic):
                total_phrases.append(mnemonic)
    return total_phrases

An diesem Punkt haben wir 180 gültige 24-Wörter-Mnemoniksätze, von denen einer Ihre Münze enthält.

Obwohl Sie all dies manuell überprüfen könnten, wäre dies eine mühsame Aufgabe. Wie in der Antwort von m1xolyd1an besprochen, können wir, wenn Sie eine der zuvor verwendeten Adressen kennen, jede dieser mnemonischen Phrasen verwenden, um die ersten 5 oder so deterministischen Adressen zu generieren, die von jeder Phrase erzeugt werden, und einen Vergleich durchführen, um nach einer Adressenübereinstimmung zu suchen.

from btctools import Xprv
import json

master_address_list = []

for phrase in total_phrases:

    m = Xprv.from_mnemonic(phrase)

    # check first few address spaces for a known match
    for i in range(0, 5):
        addr = (m/44./0./0./0/i).address('P2PKH')
        if addr == '1C26mdyEsNpe4fpkYtuHzH4Y378wez8mxP':
            master_address_list.append({addr: phrase})
        elif addr == '1BjoCJhvRCx9nVLPaKhg4qQ2YYps8mDgY4':
            master_address_list.append({addr: phrase})


print(f'Address match(s) found: ', len(master_address_list))
print(json.dumps(master_address_list, indent=4, sort_keys=True))

Wenn Adressenübereinstimmungen gefunden werden, werden diese als Schlüsselwertpaare gedruckt:

{
    "<address>": "<mnemonic phrase>"
}

Hier sind zwei Python-Skripte, die die obige Logik auf unterschiedliche Weise integrieren:

1 - Ich fürchte, Sie können keine Bitcoin-Adresse mit 23 von 24 mnemonischen Seed-Phrase-Wörtern finden/suchen.

2 - Eine weitere Katastrophe ist, die Reihenfolge der Wörter nicht zu kennen.

Weiter geht's... Mein Vorschlag ist, dass Sie einen entropywie den hexWert in diesem Beispiel generieren und speichern . Damit Sie in solchen Fällen problemlos jede Adresse abrufen können.

Der Autor erwähnt, dass er sich der Reihenfolge der anderen 23 Wörter sicher ist