Der COLDCARD-Entropiefehler: Wie ein stiller RNG-Fallback Nutzer 38 Millionen Dollar kostete

Schlüssel-Ergebnisse
- Nutzer, die auf einer COLDCARD Mk3 eine Seed-Phrase erzeugt und verwendet haben: Erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel auf die neue Wallet.
- Nutzer, die auf einer COLDCARD Mk4 oder Mk5 eine Seed-Phrase erzeugt und verwendet haben: Lag die Firmware-Version, die die ursprüngliche Seed-Phrase erzeugt hat, unter 5.6.0, erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel.
- Nutzer, die auf einer COLDCARD Q eine Seed-Phrase erzeugt und verwendet haben: Lag die Firmware-Version, die die ursprüngliche Seed-Phrase erzeugt hat, unter 1.5.0Q, erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel.
- Nutzer von OneKey-Hardware-Wallets sind von diesem Fehler nicht betroffen und können sie bedenkenlos weiterverwenden.
In der Kryptografie ist „Zufall“ eine harte Kennzahl. Er lässt sich quantifizieren und muss realer Rechenleistung standhalten.
Eine 12-Wörter-Wiederherstellungsphrase wird durch eine 128-Bit-Zufallszahl gestützt, die gemäß der BIP-39-Spezifikation in menschenlesbare Wörter kodiert wird. Wie unvorhersehbar diese Zahl ist, entscheidet unmittelbar darüber, ob die Wallet einem Brute-Force-Angriff standhält. 128 Bit bedeuten 2¹²⁸ Möglichkeiten. Bündelte man die gesamte Rechenleistung der Erde, käme man mit dem Durchprobieren dennoch nicht fertig, bevor das Universum endet.
Theoretisch sollten Hardware-Wallets darin also streng sein. Es muss einen dedizierten echten Zufallszahlengenerator (TRNG) geben, der die Zufälligkeit der physischen Welt aus Schaltkreisrauschen bezieht, gepaart mit einem EAL-zertifizierten Secure Element (SE), wobei am Ende ein ausgereifter Algorithmus alles miteinander verrührt.
Am 30. Juli 2026 wurden in weniger als einer halben Stunde rund 594 BTC (etwa 38 Millionen Dollar) aus knapp 500 COLDCARD-Wallets abgezogen. Am nächsten Tag bestätigte der Hersteller Coinkite die Grundursache in „Technical Deep Dive into the Entropy Issue“ [1]: Seit einer Firmware-Änderung im März 2021 sorgte ein Build-Konfigurationsfehler stillschweigend dafür, dass der Code auf MicroPythons eingebauten Software-Pseudozufallszahlengenerator (PRNG) zurückfiel.
Die Folgen unterscheiden sich je nach Modell. Coinkites vorläufige Schätzung lautet, dass der Mk3 nur noch etwa 40 Bit effektiven Suchraum aufweist und die Mk4, Mk5 und Q etwa 72 Bit – gegenüber einem Auslegungsziel von 128. Vierzig Bit sind rund 1,1 Billionen Möglichkeiten, was noch immer astronomisch klingt; doch für einen Angreifer, der sich einen GPU-Cluster mieten kann, ist es von „physikalisch unmöglich“ zu einem im Erwartungswert machbaren Ingenieurprojekt geworden. Von 128 auf 40 schrumpfte der Suchraum um den Faktor 2⁸⁸, also 300 Quadrilliarden.
Dieser Diebstahl von 38 Millionen Dollar hat diesen Erwartungswert zur vollendeten Tatsache gemacht.
Hinweis: Die Mittel von OneKey-Nutzern sind sicher. Kein Teil von OneKeys Code berührt dieses Problem, und keiner verwendet die betroffenen Implementierungen oder Abhängigkeiten. Vollständige Stellungnahme: https://x.com/OneKeyHQ/status/2083106588022509974?s=20
TL;DR
- Nutzer, die auf einer COLDCARD Mk3 eine Seed-Phrase erzeugt und verwendet haben: Erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel auf die neue Wallet.
- Nutzer, die auf einer COLDCARD Mk4 oder Mk5 eine Seed-Phrase erzeugt und verwendet haben: Lag die Firmware-Version, die die ursprüngliche Seed-Phrase erzeugt hat, unter 5.6.0, erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel auf die neue Wallet.
- Nutzer, die auf einer COLDCARD Q eine Seed-Phrase erzeugt und verwendet haben: Lag die Firmware-Version, die die ursprüngliche Seed-Phrase erzeugt hat, unter 1.5.0Q, erzeugen Sie sofort auf einer anderen Wallet eine neue Seed-Phrase und übertragen Sie Ihre Mittel auf die neue Wallet.
- Nutzer von OneKey-Hardware-Wallets sind von diesem Fehler nicht betroffen und können sie bedenkenlos weiterverwenden.
Und nun zum handfesten technischen Teil 👇
Grundursache: Ein stiller Software-Fallback
Von der Hardware-RNG-Schnittstelle zu libNgU
Die Migration des Krypto-Stacks von 2021 änderte die Seed-Erzeugung der Wallet von ckcc.rng_bytes() zu ngu.random.bytes() [6]:
ngu.random.bytes() → libNgU rng_get() → das rng_get-Symbol, auf das letztlich gelinkt wird
Das Risiko liegt nicht im Funktionsnamen oder in der Ausgabelänge. Es liegt darin, welche Objektdatei dieses finale rng_get() tatsächlich liefert.
#ifndef prüft nur, ob etwas definiert ist, nicht seinen Wert
Die Konfiguration des Zielboards definierte MICROPY_HW_ENABLE_RNG als 0, was bedeutete, dass MicroPythons Hardware-RNG-Pfad nicht aktiviert war.
Doch libNgU verwendete zu jener Zeit [8]:
#ifndef MICROPY_HW_ENABLE_RNG
#error ...
#endif
#ifndef testet nur, ob das Makro existiert. Ein als 0 definiertes Makro gilt weiterhin als „definiert“, sodass der #error, der einen fehlerhaften Build hätte blockieren sollen, nie ausgelöst wurde.
Ein gleichnamiges Symbol ließ die falsche Implementierung in die finale Firmware rutschen
Wenn der Hardware-RNG nicht aktiviert ist, stellt MicroPython dennoch ein rng_get() unter demselben Namen bereit – doch es handelt sich um den Yasmarang-Software-PRNG-Fallback [9].
Das ergab die vollständige Fehlerkette:
Makro existiert, aber sein Wert ist 0 → libNgUs Build-Schutz greift nicht → die Firmware kompiliert dennoch erfolgreich → das gleichnamige rng_get löst sich auf MicroPythons Fallback auf → die Seed-Erzeugung erhält nie die Hardware-RNG-Eingabe, die sie eigentlich erhalten sollte
Einzeln betrachtet ist jedes Glied dieser Kette nur ein kleines Versehen. Zusammengefügt machen sie die Torwächterfunktion des Build-Systems bedeutungslos: Dass eine sichere Implementierung im Quellcode oder in der Binärdatei existiert, bedeutet nicht, dass der sicherheitskritische Aufruf sie auch tatsächlich erreicht.
Das Mischen von Entropiequellen kann fehlende Entropie nicht ersetzen
Der Anfangszustand des Fallbacks umfasst einen Teil der UID, SysTick, die RTC-Zeit sowie den Sub-Sekunden-Zustand, wonach Yasmarang ihn deterministisch fortschreibt. libNgU mischt ihn zudem mit einem zweiten Yasmarang-Strom, der von einem festen Anfangszustand ausgeht.
Zwei deterministische Ströme, die sich rekonstruieren oder durchzählen lassen, gewinnen durch XOR-Verknüpfung oder das Durchlaufen von SHA-256 keine neue physikalische Unvorhersehbarkeit. Hashing kann die Eingabe aufbereiten, aber es kann eine endliche Kandidatenmenge nicht zu einem echten unbekannten Raum von 2^256 aufblähen.
Was 40 Bit und 72 Bit tatsächlich bedeuten
Die Schätzungen des effektiven Suchraums, die Coinkite verwendet, sind keine gemessenen oder zertifizierten Entropiewerte. Die beiden Zahlen beschreiben die Größe des Kandidaten-Zustandsraums, den ein Angreifer durcharbeiten muss. Sie sind keine Messung der Min-Entropie, sie lassen sich nicht in eine durchschnittliche Anzahl von Rateversuchen umrechnen, und sie ergeben schon gar keine bestimmte Angriffsdauer oder -kosten.
Die tatsächlichen Angriffskosten hängen von einer Kette von Voraussetzungen ab: ob der Angreifer die Geräte-UID kennt oder erraten kann; ob er den Bereich von RTC, SysTick und Bootzeit eingrenzen kann; wie viele RNG-Aufrufe vor der Seed-Erzeugung erfolgten; ob er einen xpub, eine Adresse oder einen öffentlichen Schlüssel zur Hand hat, um Kandidaten offline zu validieren; und wie teuer die BIP-39/BIP-32-Ableitung und parallele Hardware im Betrieb sind.
Die präzise Formulierung lautet daher: Unter Coinkites aktuellen vorläufigen Angriffsannahmen wird der effektive Suchraum des Mk3 auf etwa 40 Bit geschätzt und der von Mk4/Q/Mk5 auf etwa 72. Das ist nicht dasselbe wie „jede Mk3-Wallet hat genau 40 Bit Entropie“, auch nicht „für die neueren Modelle ist eine 72-Bit-Kryptosicherheit bewiesen“, und ganz sicher nicht „jeder gewöhnliche Computer kann in fester Zeit jede Wallet wiederherstellen“.
Warum auch Mk4, Mk5 und Q betroffen sind
Die beiden Secure Elements auf den Mk5- und Q-Boards (Quelle: coldcard.com)
Die beiden Secure Elements auf den Mk5- und Q-Boards (Quelle: coldcard.com)
Mk4, Mk5 und Q beziehen zwar Zufallsmaterial aus zwei Secure Elements, doch die Implementierung vor der Korrektur speiste nicht dieses gesamte Ausgabematerial in einen kryptografischen DRBG ein.
Der öffentliche Quellcode zeigt, dass nach dem Hashen des Secure-Element-Materials nur vier Bytes entnommen und an ngu.random.reseed() übergeben werden, wodurch lediglich ein 32-Bit-Zustandswort von Yasmarang ersetzt wird.
Wenn also der restliche Fallback-Zustand und die Aufrufspur festliegen:
Anzahl der durch das Secure-Element-Reseed unterscheidbaren Ausgabeströme ≤ 2³²
Dies widerspricht nicht den offiziellen „etwa 72 Bit“. Das 72-Bit-Modell rechnet auch die Unsicherheit in Zuständen wie UID, Timern, RTC und Aufrufhistorie mit ein. Block Engineerings lockere kombinierte Obergrenze liegt unter 2^73,3, und sie stellen ausdrücklich klar, dass dies keine Zertifizierung einer 73-Bit-Kryptosicherheit ist [10].
Mit anderen Worten: Der Mk3 ist der schlimmste Fall, weil es überhaupt kein sicheres Reseed gibt. Die Secure-Element-Eingabe bei Mk4/Q/Mk5 senkt das Risiko, doch ein Vier-Byte-Reseed stellt die 128-Bit-Sicherheit, die das Design anstrebte, nicht wieder her.
Die offizielle Warnung und der tatsächliche Umfang
Coinkites aktuelle Warnung beginnt bei Mk3 4.0.1. Doch der unveränderliche v4.0.0-Quellcode enthält bereits den relevanten Entropieerzeugungspfad [7], und zwischen 4.0.0 und 4.0.1 gibt es keine entsprechende RNG-Korrektur.
Block Engineering geht weiter und bezieht auch Mk2/Mk3 v4.0.0–v4.1.9 in seine Quellcode-Analyse ein [10].
Es gibt also zwei Ebenen, die man auseinanderhalten sollte:
- Coinkites offizieller Umfang: Mk3 4.0.1+;
- der technische Umfang, den der Quellcode stützt: Mk2/Mk3 v4.0.0–v4.1.9.
Man kann nicht sagen, dass Coinkite Mk2 oder v4.0.0 offiziell bestätigt hat. Ebenso wenig kann man daraus, dass die Warnung sie nicht nennt, ableiten, dass sie sicher sind.
Wie die Korrektur funktioniert
Der Hotfix in Mk4/Mk5 5.6.0 und Q 1.5.0Q änderte mehr als nur einen Bedingungsausdruck. Er fügte eine Durchsetzung auf Build-Ebene hinzu [3][4][5]:
- MicroPythons Fallback-RNG-Objekt ausschließen;
- sicherstellen, dass das Objekt auf Board-Ebene das globale
rng_get()bereitstellt; - mit
nmdie Symbole in den Objektdateien inspizieren; - den Build sofort scheitern lassen, wenn der Fallback das Symbol weiterhin exportiert oder das Objekt auf Board-Ebene
rng_get()nicht ordnungsgemäß bereitstellt.
Was Nutzer tun sollten
Mk4, Mk5 und Q
- Aktualisieren Sie zunächst auf 5.6.0 oder höher (Mk4/Mk5) bzw. 1.5.0Q oder höher (Q).
- Erzeugen Sie auf der korrigierten Firmware einen brandneuen Seed.
- Notieren Sie das Backup und führen Sie eine Wiederherstellungsprüfung durch.
- Prüfen Sie den Wallet-Fingerabdruck und die Empfangsadresse auf dem Gerätebildschirm.
- Senden Sie eine kleine Testtransaktion, bevor Sie den Rest Ihrer Mittel migrieren.
- Bewahren Sie das alte Backup auf, bis jede Überweisung bestätigt ist, empfangen Sie aber nichts mehr auf der alten Wallet.
Mk3
Derzeit gibt es keine veröffentlichte Korrektur-Firmware für den Mk3, und 4.1.9 ist keine Korrektur. Nutzer sollten nicht auf Firmware warten, die möglicherweise später kommt, denn keine neue Firmware kann einem bestehenden Seed Entropie hinzufügen.
Folgen Sie Coinkites aktueller Migrationsanleitung: Erzeugen Sie einen neuen Seed auf einem vertrauenswürdigen Pfad, prüfen Sie das Backup, die Adressen und eine kleine Transaktion und migrieren Sie dann Ihre Vermögenswerte.
Zwei unterschiedliche Würfel-Schwellenwerte
Beim Würfeln gibt es zwei Zahlen: 50 und 99. Sie dienen zwei unterschiedlichen Zwecken und lassen sich nicht austauschbar verwenden.
50+ Würfe, die bei der ursprünglichen Seed-Erzeugung hinzugefügt wurden. Wurden bei der erstmaligen Erzeugung des Seeds mindestens 50 faire, unabhängige, private Würfe eines sechsseitigen Würfels eingemischt, die nie aufgezeichnet, gespeichert oder offengelegt wurden, so betrachtet Coinkite diesen Seed allein aufgrund dieses RNG-Problems nicht als gefährdet [11].
50 × log₂(6) ≈ 129,25 Bit
Das ist der Schwellenwert von rund 128 Bit für diesen konkreten Vorfall, kein absoluter Sicherheitsbeweis für Ihren gesamten Betriebsablauf.
Der Dice-Roll-Import-Ablauf auf einer leeren Mk3. Coinkite bietet außerdem einen anderen Ablauf: Wählen Sie auf einer leeren Mk3 mit 4.1.9 Import Existing > Dice Rolls und geben Sie mindestens 99 faire Würfe ein. Dieser dedizierte Pfad verarbeitet die Würfelsequenz direkt und nutzt nicht den betroffenen Gerätegenerator.
99 × log₂(6) ≈ 255,91 Bit
99 ist der Schwellenwert im offiziellen Ablauf; rechnet man von einem wörtlichen Standard von „mindestens 256 Bit“ zurück, bräuchte man 100.
Eine Passphrase ist eine eigene Barriere, keine Korrektur
Eine starke, einzigartige, zufällige, geheime BIP-39-Passphrase leitet eine andere Wallet ab und kann einen unabhängigen Suchfaktor hinzufügen; die Geräte-PIN steuert nur den lokalen Zugriff und ist an der Ableitung des BIP-39-Wurzelschlüssels nicht beteiligt [12].
Doch eine Passphrase kann Entropie nicht ersetzen, die der Mnemonik nie zu eigen war. Kurze Passphrasen, berühmte Zitate, vorhersehbare Muster und wiederverwendete Passwörter lassen sich weiterhin erraten. Ein Tippfehler erzeugt zudem eine Wallet, die gültig aussieht, aber völlig anders ist – deshalb müssen Sie den Fingerabdruck überprüfen und ein zuverlässiges Backup aufbewahren, dessen Wiederherstellung Sie getestet haben.
Schlusswort
Das Kernproblem, das dieser Vorfall offengelegt hat, ist, dass die tatsächliche Erreichbarkeit einer sicherheitskritischen Implementierung nie vom Build-System erzwungen wurde. „Jemand hat ein Makro falsch gemacht“ beschreibt das bei Weitem nicht.
Hardware-Wallets und andere Schlüsselerzeugungssysteme sollten mindestens:
- überprüfen, auf welches Objekt und Symbol eine Sicherheits-API letztlich linkt, und nicht nur die Funktionssignatur kontrollieren;
- Fähigkeitsprüfungen sowohl die Existenz als auch den Wert eines Makros verifizieren lassen;
- sicherheitskritische Fallbacks fail-closed gestalten, sodass niemals stillschweigend ein gewöhnlicher PRNG geliefert wird;
- die CI die Objektzusammensetzung, Link-Maps, die Symbolherkunft und den End-to-End-Datenfluss inspizieren lassen;
- durch Tests nachweisen, dass echte Hardware-Entropie den finalen Seed erreicht, statt nur Ausgabelänge, Nicht-Null-Wert oder das Fehlen von Wiederholungen zu prüfen;
- Warnhinweise verfassen, die klar zwischen der Version, die den Seed erzeugt hat, der aktuellen Firmware, der korrigierten Version und dem Umgang mit alten Seeds unterscheiden.
Dass COLDCARD Open Source ist, ermöglichte es externen Forschern, diese Aufrufkette zu rekonstruieren, und Coinkite konnte sowohl einen formellen technischen Bericht als auch ein korrigiertes Release veröffentlichen.
Die Behauptung, eine Marke sei „absolut sicher“, ist nichts wert. Wertvoll ist es, „woher der Zufall kommt, worauf er letztlich linkt, wohin er im Fehlerfall geht und wie man das im ausgelieferten Produkt überprüft“ zu einer Systemeigenschaft zu machen, die man immer wieder neu nachprüfen kann.
Quellen
[1] Coinkite: Technical Deep Dive into the Entropy Issue [2] Coinkite: Mk3 Security Advisory [3] Coldcard 5.6.0 / 1.5.0Q fix commit [4] Coldcard 5.6.0 release commit [5] Coldcard 1.5.0Q release commit [6] 2021 libNgU seed generation migration commit [7] Official v4.0.0 source snapshot [8] libNgU random.c [9] MicroPython commit introducing the fallback [10] Block Engineering technical analysis [11] Coldcard dice roll math [12] Coldcard passphrase documentation [13] OneKey trezorcrypto.random source branch [14] OneKey seed generation logic [15] OneKey standard Makefile [16] OneKey SCons config






