Hier gehts zum Beitrag auf der Webseite:
Alten Beitrag hier ausklappen
Moin zusammen!
In diesem Beitrag solll es rund um das Thema Ableitungspfade gehen und wie eine Wallet es schafft aus unsereren 24 Wörtern praktisch unendlich viele Schlüssel abzuleiten. Mir ist bewusst das dies ein eher unwichtigeres Thema (für den Endnutzer) ist, weshalb ich versucht habe den Beitrag in aufsteigender Schwierigkeit zu schreiben.
Das heisst die ersten Absätze sollten für alle verständlich (und wichtig) sein während es gegen Ende etwas mehr ins Detail geht. Das Thema ist teilweise sehr abstrakt, deswegen scheut euch nicht offene Fragen direkt hier im Thread zu stellen. :)
Los geht’s!
Eine Wallet ist nur ein Schlüssel(bund)
Um wirklich alle abzuholen müssen wir uns zunächst einmal klar machen was eine Wallet konkret überhaupt ist. Hier ein paar Mythen die wir erstmal aus dem Weg räumen müssen bzw. einige Formulierungen die wir konkretisieren:
-
Eine Wallet kontrolliert keine Bitcoin - sondern Schlüssel zu den Bitcoin.
-
Bitcoin liegen nicht auf einer Wallet - sondern Schlüssel liegen auf der Wallet.
-
Eine Mnemonic/Seedphrase ist kein Backup der Bitcoin - sondern ein Backup der Schlüssel zu den Bitcoin.
-
Der Seed, die Schlüssel und sogar Adressen sind nichts anderes als große Zahlen, die in besser lesbaren Zahlensystemen wie z.B. Base58 codiert sind.
Vielleicht denkt man sich: Wo ist denn da der Unterschied?
Ein Ersatzschlüssel eurer Wohnung ist kein Ersatz für eure Wohnung, sondern ein Ersatz für den Zugang zur Wohnung. Anders als bei einer Wohnung müssen wir uns um die Sicherheit der Bitcoin selbst absolut keine Gedanken machen, da diese unveränderlich auf einer dezentralen Datenbank (der Blockchain) gesichert sind.
Deshalb verändert auch eine ein- oder ausgehende Transaktion nichts an den Backups, da die Schlüssel immer noch die selben sind. Egal wie viele Bitcoin wir empfangen oder ausgeben, unser Anfangs erstelltes Backup ist immer noch gültig, da die Schlüssel gleich geblieben sind.
Wieder das Beispiel Wohnung: Wenn wir uns einen neuen Schrank ins Schlafzimmer stellen, bleibt der Haustürschlüssel der gleiche.
Worüber wir uns also Gedanken machen müssen: Die Sicherheit unserer Schlüssel!
Nicht-deterministische Wallets
Heutzutage benutzen die wenigsten von uns noch sogenannte nicht-deterministische Wallets (auch random wallets gennant), da sie in der Benutzung extrem unpraktisch sind. Wir alle kennen das Konzept einer Mnemonic, also den Wiederherstellungswörtern, doch das gibt es bei einer nicht-deterministischen Wallet nicht.
Vereinfacht: Zu jeder Adresse gehört ein öffentlicher Schlüssel, und zu diesem öffentlichen Schlüssel gehört ein privater Schlüssel. Diese Ableitung funktioniert nur in eine Richtung:
Privater Schlüssel → Öffentlicher Schlüssel → Adresse
Die Adresse brauche ich um Bitcoin zu empfangen, den privaten Schlüssel um die Bitcoin auf der Adresse auszugeben und den öffentlichen Schlüssel um zu beweisen dass der private Schlüssel auch wirklich zu dieser Adresse gehört.
Bei einer nicht-deterministischen Wallet stehen alle Schlüsselpaare für sich und haben nichts miteinander zu tun. Das bedeutet: Jeder private Schlüssel muss einzeln abgesichert werden, da ich keinen „Hauptschlüssel“ habe mit dem ich auf alle anderen Schlüssel zurück schließen kann.
Das ist extrem unpraktisch. Erstens, weil es sowieso schon mühsamer ist einen komplexen Schlüssel zu notieren (anstatt einfache englische Wörter) und zweitens, weil ich für jede neue Adresse die ich generiere auch wieder ein neues Backup machen muss. Das kollidiert mit dem gewünschten Anreiz augrund von Privatsphäre immer neue Adressen zu verwenden.
Viele von euch haben so eine Wallet trotzdem schon einmal benutzt, denn eine einfache Paper Wallet ist nichts anderes als eine nicht-deterministische Wallet. Auch die allererste Bitcoin Wallet (in Bitcoin Core) ist bis heute eine solche zufällige und ungeordnete Wallet.
Wir merken uns: Unsere Schlüssel fliegen wahllos im Geldbeutel rum und haben keinen Bezug zueinander. Das ist unpraktisch und in der Nutzung auch mit erheblichen Risiken behaftet.
Bild: Mastering Bitcoin, Kapitel 5 – LINK
HD Wallets
Jetzt bringen wir etwas mehr Ordnung ins Spiel und kommen zur heute gängigen hierarchisch-deterministischen Wallet, die wahrscheinlich jeder von euch selbst benutzt.
Anders als beim vorherigen Beispiel stehen unsere Schlüssel in direkter Beziehung zueinander und wurden alle aus einem Generalschlüssel abgeleitet, auch bekannt als Seed.
Bild: Mastering Bitcoin, Kapitel 5 – LINK
Wir haben jetzt nur noch einen Generalschlüssel mit dem wir beliebig viele, ja sogar praktisch unendlich viele Schlüssel bzw. Adressen ableiten können. Diesen Generalschlüssel erzeugen wir mit Hilfe einer langen Zufallszahl, und diese Zufallszahl können wir auch in lesbare Wörter codieren, um einen einfachen Backup-Prozess zu ermöglichen:
worth unknown mean plastic neglect flip guilt library ripple explain destroy thing rival put usage tackle craft cheese
256 bit Entropie (+ 8 bit Checksumme) codiert als Mnemonic
ist deutlich praktischer als
fdfdbe27530940b219ec08ba4a10f0f05bab5dbbe6e83204
Die selben 256 bit Entropie in Hexadezimal
Auch wenn uns dieses geordnetere Konstrukt das Leben deutlich leichter macht stehen wir jetzt vor einem Problem.
Der Begriff hierarchisch bedeutet hier dass wir in einer Baumartigen Struktur von unten (Seed – Wurzel) nach oben (Krone) ableiten. Wie bei einem Baum gibt es hier keinen eindeutigen Weg, sondern wir können beliebige Verästelungen einschlagen auf dem Weg bis zur Krone.
Bild: Mastering Bitcoin, Kapitel 5 – LINK
Auf dieser Grafik sehen wir, wie aus dem Seed ein Schlüssel generiert wird. Aus diesem Schlüssel werden wiederum neue Schlüssel generiert, aus denen wiederum neue Schlüssel generiert werden, aus denen wiederum… immer so weiter.
Wer schon einmal einen vollständigen Familien-Stammbaum zusammengesetzt hat weiß, wie schwierig es sein kann überhaupt den Platz zu finden alles passend anzuordnen, da aus Uroma und Uropa ganz schön viele Urenkel enstanden sind.
Anders als bei einer Familie haben wir in unserer Wallet aber keine biologischen Grenzen, sondern können uns komplett austoben. :)
Ein Beispiel mit willkürlichen Zahlen:
Ich könnte aus dem Hauptschlüssel 1000 neue Schlüssel ableiten, dann den 476-sten nehmen und daraus 30 Schlüssel ableiten, dann den 4-ten Schlüssel nehmen und daraus 5.000.000 Schlüssel ableiten, dann den 3.993.127-sten Schlüssel nehmen und daraus dann einen Schlüssel ableiten.
Diesen Schlüssel nehme ich um mir eine Adresse zu erzeugen und meine Bitcoin abzusichern. Bis hier kein Problem.
Sobald ich aber mit meiner Mnemonic (d.h. dem Hauptschlüssel) wiederherstellen will muss ich den exakten Pfad zu dem Schlüssel der Adresse kennen um meine Bitcoin ausgeben zu können. Ich kontrolliere zwar mit meiner Mnemonic auch diesen einen Schlüssel, das bringt mir aber relativ wenig wenn ich nicht weiß wo er ist.
Derivation Paths
Jetzt da wir das Problem verstanden haben können wir eine relativ einfache Lösung dafür finden: Einen Wegweiser.
Den sogenannten Master Private Key (der direkt aus dem Seed abgeleitet wird) nennen wir ab jetzt m
und den entsprechenden Master Public Key nennen wir M
.
m/0
ist dann der erste Child Key von m
, während m/1
der zweite Child Key von m
wäre. Beide sind auch oben in der Grafik zu sehen!
Jetzt tasten wir uns Schrittweise im Ableitungspfad vor und benutzen um Verwirrung zu vermeiden Familienbezeichnungen aus Sicht der Eltern (m
):
-
m/0/0
ist dann der erste Enkel vom ersten Kind. -
m/1/0
ist dann der erste Enkel vom zweiten Kind. -
m/0/0/0
ist dann der erste Urenkel vom ersten Enkel vom ersten Kind. -
m/1/2/3/4
ist dann der fünfte Ur-Urenkel vom vierten Urenkel vom dritten Enkel vom zweiten Kind.
Langsam wird es kompliziert, aber ich denke wir haben verstanden wir der Wegweiser vom Prinzip her funktioniert. Falls nein: Lest euch diesen Abschnitt einfach mehrmals durch. Es ist anfangs vielleicht etwas abstrakt, das ist völlig normal.
Versuchen wir mal meinen absichtlich komplizierten Ableitungspfad von oben in dieses System umzusetzen:
Probier es erstmal selbst und klappe dann die Lösung auf
m/475/3/3993126/0
Achtung: Wir fangen in der Informatik mit 0
an zu zählen!
Den Ausdruck in Worten sparen wir uns besser.
Unser Problem wurde allerdings noch nicht gelöst. Wir stehen immernoch vor unendlich vielen Ableitungspfaden, die wir jetzt zwar eindeutig benennen können aber unsere Wallet müsste sie trotzdem erstmal alle absuchen, da sie alleine mit den 12 oder 24 Wörtern nicht weiß, wo sie hin muss.
Bei der unfassbar großen Anzahl an Möglichkeiten wäre dies schlichtweg unmöglich. Wenn jeder Entwickler sein eigenes Ableitungssüppchen kocht schadet das am Ende nur dem Nutzer da er nicht weiß wie er seine Schlüssel wiederherstellen kann.
Wir brauchen einen Standard
Und den gibt es! Um das einheitliche Ableiten zwischen verschiedenen Adresstypen und verschiedener Software zu ermöglichen hat man sich auf einen bestimmten Bauplan für den Ableitungspfad geeinigt.
Begonnen hat das in BIP-44, indem man eine bestimmte Funktion für jeden Ableitungsschritt vereinbart.
m/44'/0'/0'/0/0
-
Die erste Stelle steht für den Purpose, also welcher konkrete Standard verwendet wird. Der Endnutzer kann damit auch bereits auf den Adresstyp schließen den seine Wallet am Ende für ihn ableitet. In diesem Fall generieren wir traditionelle P2PKH (Legacy) Adressen, die mit einer
1
anfangen.Wir nehmen hier also immer den 45-sten Child Key.
-
Die zweite Stelle steht für den Coin Type, also um welchen Coin es gehen soll. Für Bitcoin nutzen wir
0
, für das Bitcoin Testnet nutzen wir1
, für Litecoin nutzen wir2
, …Wir nehmen hier also den ersten Grandchild Key für Bitcoin.
-
Die dritte Stelle steht für den Account. Davon haben sicherlich die meisten schonmal etwas gehört und das ist auch die einzige Schnittstelle die man als normaler Nutzer mit dem Derivation Path hat.
Wir nutzen diese Stelle im Pfad um uns effektiv „Unterkonten“ in unserer Wallet zu erstellen. Das hat einen reinen organisatorischen Vorteil, da wir bestimmte Adressen voneinander trennen und bestimmte Teile unserer Wallet für bestimmte Funktionen reservieren können (Sparen, Shoppen, Kinder, …).
Da wir immer noch von einem Standard sprechen können wir diese Accounts einfach zwischen verschiedenen Wallets (Software) übertragen und landen immer bei den gleichen Schlüsseln und damit Accounts.
Die Funktionen in der Ledger Live oder BitBox App machen genau das selbe. Sie kennen diesen Standard und wissen wo sie im Ableitungsbaum suchen müssen um zu anderen Accounts zu gelangen.
Wir benutzen hier also
0
um in unserem „Standard Account“ zu landen und können dann durch erhöhen des Index beliebig viele Konten „erstellen“, die natürlich alle zu unserer Mnemonic gehören und jederzeit abgeleitet werden können. Wir gehen jeweils einfach auf einen anderen Ast. -
Die vierte Stelle unterscheidet zwischen Receiving und Change Adressen. Um zu verstehen was das ist empfehle ich dir meinen Beitrag zu Unspent Transaction Outputs (UTXO).
Wir benutzen
0
für normale Empfangsadressen und1
für Wechseladressen.
Erst jetzt erreichen wir die eigentlichen Schlüssel die unsere Bitcoin kontrollieren!
-
Die letzte Stelle steht dann letztendlich für die eigentlichen Schlüsselpaare die wir für unsere Adressen alltäglich verwenden.
Index
0
steht also für die erste Adresse bzw. die ersten Schlüssel, Index1
für die zweite und immer so weiter. Wenn wir eine neue Adresse „generieren“ schaltet unsere Wallet einfach den Derivation Path an dieser Stelle um einen Index weiter. Jede Adresse bzw. jeder private Schlüssel hat einen eindeutigen Ableitungspfad.
Hier nochmal zusammengefasst in einer Grafik:
Bild: Greg Walker – learnmeabitcoin.com/technical/derivation-paths
m/44’/0’/0’/0/0
… leitet also die erste Receiving Bitcoin Legacy Adresse nach BIP-44 ab, die sich im ersten Account befindet.
m/84’/0’/1’/0/3
… leitet die vierte Receiving Bitcoin Native Segwit Adresse nach BIP-84 ab, die sich im zweiten Account befindet.
Meine Bitcoin werden nicht angezeigt
Mit unserem neuen Wissen können wir uns jetzt einen häufigen Grund für scheinbar „verschwundene“ Bitcoin erschließen: Etwas stimmt mit der Ableitung bzw. dem Ableitungspfad nicht.
Sichern wir einen Teil unserer Bitcoin z.B. in einem zweiten Account (z.B. Account #1: m/44’/0’/1’/…) und unsere Wallet weiß nichts davon, dann werden diese Bestände in der Übersicht auch nicht angezeigt. Natürlich kontrollieren wir diese Bestände trotzdem – unsere Bitcoin sind in Sicherheit, nur haben wir die entsprechende „Schublade“ noch nicht geöffnet.
Das erneute „Hinzufügen“ des Accounts führt dann dazu dass die Wallet Software den entsprechenden Pfad in der Ableitung absucht und alle Bestände die sie dabei findet auch wieder anzeigt.
Bei der BitBox02 ist dies zumindest so der Fall. Nutzt man seine BitBox02 an einem neuen Rechner oder Android Smartphone bzw. installiert die BitBox App neu, dann werden nicht automatisch alle Accounts abgesucht. Man muss manuell alle Accounts wieder aktivieren.
Edit: Mit der neuen BitBoxApp-Version (Juni 2023) werden Accounts automatisch abgesucht. Das Problem sollte also nicht mehr auftreten! :)
Gap Limits
In der Regel zeigt euch eure Wallet Software immer die nächsten 20 Adressen an, die noch nicht benutzt worden sind. Diese Zählung beginnt immer ab der letzten verwendeten Adresse. Bedeutet: Auch wenn Adressen 1-19 unbenutzt sind, ihr aber Adresse 20 verwendet habt, dann werden euch jetzt die Adressen 21-40 angezeigt. Lasst euch davon also nicht verwirren.
Es kann (z.B. nach einem CoinJoin) passieren dass eure Bitcoin auf Adressen mit einem sehr hohen Index landen, der vom Gap Limit eurer Software nicht abgedeckt ist, d.h. euch werden die Bestände nicht angezeigt.
Genau das ist z.B. einem Nutzer in diesem Thread passiert:
Die Lösung lautet hier, ähnlich wie mit den Accounts, die entsprechenden Adressen einfach abzusuchen. Software wie die Sparrow Wallet unterstützen hierfür das manuelle erhöhen des Gap Limits, also der Anzahl an Adressen die nach der Adresse mit höchstem Index abgesucht werden sollen.
Auch die BitBox App kann man mit einem Argument starten um das Gap Limit anzupassen:
Verstecken spielen
Wer jetzt auf die großartige Idee kommt dass man manuell seine Bitcoin auf einem unkonventionellen Ableitungspfad absichern könnte, damit man selbst mit der Mnemonic die richtigen Schlüssel zunächst nicht findet, den versuche ich hier direkt aufzufangen.
Nein, bitte macht das nicht!
Es ist grundsätzlich nicht ratsam und immer mit Risiken verbunden vom Standard abzuweichen.
Gründe die gegen dieses Vorgehen sprechen:
-
Das Verstecken im Ableitungspfad bietet keine Sicherheit, sondern höchstens Zeit. Mit der Mnemonic hat ein Angreifer eigentlich alles was er wissen muss, es ist nur eine Frage der Zeit bis er den richtigen Schlüssel findet. Es ist die Suche nach der Nadel im Heuhaufen – aber die ist nicht unmöglich.
-
Es gibt standardisierte Verfahren für mehr Sicherheit. Zum Beispiel eine optionale Passphrase, die tatsächlich auch mehr Sicherheit bietet.
-
Ihr macht es euren Erben noch komplizierter als es wahrscheinlich ohnehin schon ist.
-
Nicht jede Wallet Software erlaubt es euch einen beliebigen Ableitungspfad zu besuchen. Ihr schränkt eure Optionen damit extrem ein.
Bleibt beim Standard, d.h. das einzige das ihr am Derivation Path anpasst ist der Account Index. Das wars.
Extended Keys
Nachdem wir jetzt verstanden haben wie HD Wallets funktionieren können wir uns erweiterte Schlüssel wie den beliebten xpub (Extended Public Key) genauer anschauen.
Am besten schauen wir uns dafür wieder Ableitungspfade an, konkret diese drei Public Keys bzw. Adressen:
(Erinnerung: Großes M
als Abkürzung für Public Key)
- M/84’/0’/0’/0/0
- M/84’/0’/0’/0/1
- M/84’/0’/0’/0/2
Hat man einen der drei Schlüssel kann man damit nicht auf die anderen beiden schließen. Geschwister können sich untereinander nicht ableiten (genauso wenig wie sie sich biologisch fortpflanzen können – die Analogie funktioniert immer noch). Nur der Parent Key kann alle Child Keys ableiten, nicht anders herum. Eltern können Kinder kriegen, aber Kinder keine Eltern.
Wenn wir jemandem eine Bitcoin Adresse für eine Bezahlung geben, dann möchten wir schließlich nicht dass er damit alle anderen Adressen ableiten kann und damit unsere Bestände kennt. (Hinweis: Könnte er sowieso nicht solange er den Public Key nicht kennt – Dieser wird bei einer Transaktion aber veröffentlicht)
Trotzdem brauchen wir einen Weg unsere Adressen „in einem Schlüssel“ zu speichern, ohne unsere kritischen Geheimnisse wie z.B. die Mnemonic Preis zu geben. Die Wallet Software die wir mit unserer Hardware Wallet verwenden muss zwar unsere Transaktionen und Adressen kennen, darf aber nicht an Private Schlüssel gelangen.
Die Lösung: Wir verwenden den Public Key des jeweiligen Accounts, also zum Beispiel:
- M/84’/0’/0’
… kann alle Adressen bzw. alle Public Keys (inkl. Change) des Accounts #0 derivieren – aber keine Private Keys!
GIF: Greg Walker – learnmeabitcoin.com/technical/hd-wallets
Diesen 256 bit Schlüssel codieren wir zusammen mit dem sogenannten Chain Code, der für das derivieren notwendig ist in einen 512 bit Extended Public Key (xpub):
xpub67xpozcx8pe95XVuZLHXZeG6XWXHpGq6Qv5cmNfi7cS5mtjJ2tgypeQbBs2UAR6KECeeMVKZBPLrtJunSDMstweyLXhRgPxdp14sk9tJPW9
Was ist der Chain Code? Der Einfachheit halber habe ich diesen Teil des Ableitungsprozesses während dieses Beitrages unterschlagen, da er für den normalen Nutzer auch völlig irrelevant ist. Ich empfehle Kapitel 5 aus Mastering Bitcoin oder die unten verlinkten learnmeabitcoin Seiten wenn man hier noch tiefer einsteigen will. Selbiges gilt für das Konzept der gehärteten Ableitung (Hardened Derivation).
Links
-
Mastering Bitcoin, Andreas M. Antonopoulos, Kapitel 5: Wallets
-
Die großartigen Erklärungen von Greg Walker zu:
Forum:
- Was ist ein "Unspent Transaction Output" (UTXO) und was muss man beachten? - #25 von sutterseba
- Coins auf Nuri/Bitwala können gesperrt werden
- Bitbox Kontenübersicht auf zwei Notebooks unterschiedlich
- Bitcoin Account Höhe checken
- Suchergebnisse für „derivation path“ - Blocktrainer Forum
Der Beitrag ist länger geworden als gedacht
Hoffe es war hilfreich und ihr konntet was neues dazu lernen – Wie immer sofort mit Kritik und Feedback melden sollte irgendetwas inhaltlich nicht stimmen!