Teil 1 von Beyond Secure Storage untersuchte den Missbrauch der eigenen Signierfunktion eines Zahlungssystems. Dieser zweite Teil befasst sich mit einem anderen Weg zu unautorisierten Signaturen: Fehler bei der Implementierung kryptografischer Verfahren, durch die ein Angreifer einen privaten Schlüssel rekonstruieren und eigenständig signieren kann. Die Frage lautet: Kann ein Angreifer einen Schlüssel rekonstruieren, ohne dessen geschützte Kopie auszulesen?
Abschnitt 1 legt die Sicherheitsanforderungen für die Schlüsselerzeugung, -speicherung und das Signieren fest. Die Abschnitte 2 und 3 untersuchen vier Vorfälle bei der Schlüsselerzeugung und zwei beim Signieren und erläutern die Implementierungsfehler und ihre Folgen. Abschnitt 4 leitet aus diesen Fällen Grundsätze für Entwurf und Implementierung ab und erklärt anschließend, wie sich die erforderlichen Eigenschaften überprüfen lassen.
1. Sicherheitseigenschaften über den gesamten Lebenszyklus eines Schlüssels
Ein Schlüssel muss erzeugt, gespeichert und zum Signieren verwendet werden. Jede Phase stellt eine andere Sicherheitsanforderung, wie die Abbildung zeigt.

In einer hierarchisch-deterministischen Wallet mit mnemonischen Phrasen nach BIP-39 und Schlüsselableitung nach BIP-32 werden kryptografisch sichere Zufallsdaten in eine mnemonische Phrase codiert und in einen Seed umgewandelt. Aus diesem Seed werden private Schlüssel, öffentliche Schlüssel und Wallet-Adressen abgeleitet [1, 2].
Nach ihrer Erzeugung müssen Seeds und private Schlüssel durch Verschlüsselung oder Hardwareisolierung geschützt werden. Beim Signieren wird der private Schlüssel verwendet, um eine öffentlich überprüfbare Signatur zu erzeugen. Je nach Verfahren kann dafür auch eine sicher erzeugte zufällige Nonce oder eine deterministisch aus geheimem Material abgeleitete Nonce erforderlich sein.
Die Sicherheitsanforderungen unterscheiden sich zwischen diesen Phasen:
- Unvorhersehbarkeit bei der Erzeugung. Ein Angreifer darf das Geheimnis, das die Wallet kontrolliert, weder vorhersagen noch mit vertretbarem Aufwand durchprobieren können.
- Vertraulichkeit bei der Speicherung. Unbefugte dürfen geheimes Material weder über Software noch über physische Schnittstellen, Backups, Protokolle oder entfernte Dienste auslesen können.
- Keine Preisgabe bei der Verwendung. Beim Signieren dürfen nicht genügend Informationen offengelegt werden, um das Geheimnis zu rekonstruieren – auch nicht nach vielen öffentlich einsehbaren Signaturen.
Hardware-Wallets, Secure Elements und Trusted Execution Environments (TEEs) können die Vertraulichkeit stärken. Ihre bloße Verwendung gewährleistet jedoch nicht die beiden anderen Eigenschaften. Ein vorhersagbarer Schlüssel bleibt vorhersagbar, nachdem er sicher gespeichert wurde; mathematische Informationen, die Signaturen offenlegen, bleiben verfügbar, selbst wenn die Bytes des privaten Schlüssels vom Host isoliert sind. Ein Angreifer kann daher unter Umständen einen betroffenen Schlüssel rekonstruieren und auf die von ihm kontrollierten Vermögenswerte zugreifen, ohne die gespeicherte Kopie auszulesen.
Die nächsten beiden Abschnitte untersuchen, wie Implementierungen gegen diese Anforderungen verstoßen: Fehler bei der Erzeugung können Schlüssel vorhersagbar machen, während Fehler beim Signieren ihre Rekonstruktion aus öffentlichen Signaturen ermöglichen können. Diese Fälle bilden die Grundlage für die Implementierungsgrundsätze und Prüfziele in Abschnitt 4.
2. Fehlerhafte Schlüsselerzeugung: vorhersagbare private Schlüssel
Bei der Schlüsselerzeugung muss die Unvorhersehbarkeit in jedem Schritt erhalten bleiben. Die Entropiequelle muss für kryptografische Zwecke geeignet sein, ihr Zustand darf sich in der Praxis nicht vollständig durchprobieren lassen, und bei der Umwandlung von Zufallsbytes in einen Seed oder privaten Schlüssel muss die vorgesehene Ungewissheit erhalten bleiben. Ein Sicherheitsziel von 128 Bit erfordert einen Raum möglicher Geheimnisse, der sich durch Implementierungsfehler nicht auf eine mit vertretbarem Aufwand durchsuchbare Größe reduzieren lässt.
Die Tabelle fasst vier Möglichkeiten zusammen, wie diese Eigenschaft bei der Erzeugung verloren gehen kann: ein schwacher Zufallszahlengenerator in einer Bibliothek, eine fehlerhafte Anbindung eines Zufallszahlengenerators (RNG), eine verlustbehaftete Umwandlung der Eingabe und ein Generator mit einem begrenzten Anfangszustand. Die Angaben zu den Auswirkungen stammen aus Berichten über unterschiedliche Zeiträume; sie sind keine zum selben Stichtag ermittelten Gesamtzahlen.
| Vorfall | Relevanter Zeitraum | Gemeldete Auswirkungen (ca.) | Nachfolgend untersuchte Fehlerursache |
|---|---|---|---|
| Ill Bloom | Mai–Juli 2026 | ~5 Millionen USD als Untergrenze, Stand: 13. Juli | Schwacher Zufall bei der Erzeugung mnemonischer Phrasen |
| Coldcard | Ab 30.07.2026; Bilanz vom 14. August | 112,70 Millionen USD | Fehlerhafter RNG-Pfad in der Firmware |
| XRPH Wallet | 03.09.2026 | 450 Tausend USD | Vorhersagbare, stark eingeschränkte Eingaben für die Wallet-Erzeugung |
| Qubic Wallet | 17.10.2026–18.10.2026 | 1,3 Millionen USD | Unsichere Seed-Erzeugung mit Math.random() |
2,1 Ill Bloom: schwacher Zufall in einer Wallet-Abhängigkeit
Beim Ill-Bloom-Vorfall erzeugten einige Software-Wallets BIP-39-Wiederherstellungsphrasen mit anfälligen Versionen von crypto-js. Die Funktion CryptoJS.lib.WordArray.random() der Bibliothek verwendete einen eigenen Multiply-With-Carry-Generator (MWC), der mit Math.random() initialisiert wurde, statt Entropie aus einer kryptografisch sicheren Quelle zu beziehen. Wallets, die diese Funktion als sicherheitskritische Entropiequelle nutzten, übernahmen die Schwächen des Generators – selbst wenn die anschließenden Schritte zur Erzeugung der mnemonischen Phrase und zur Schlüsselableitung den jeweiligen Standards korrekt folgten [3].
Die anfällige Implementierung von crypto-js v3.1.9-1 [4] enthält diese charakteristische Logik:
random: function (nBytes) {
var words = [];
var r = (function (m_w) {
var m_w = m_w;
var m_z = 0x3ade68b1;
var mask = 0xffffffff;
return function () {
m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
var result = ((m_z << 0x10) + m_w) & mask;
result /= 0x100000000;
result += 0.5;
return result * (Math.random() > .5 ? 1 : -1);
}
});
for (var i = 0, rcache; i < nBytes; i += 4) {
var _r = r((rcache || Math.random()) * 0x100000000);
rcache = _r() * 0x3ade67b7;
words.push((_r() * 0x100000000) | 0);
}
return new WordArray.init(words, nBytes);
}
Dabei ist r() der eigene MWC-basierte Generator, während Math.random() bei der Initialisierung seines Zustands hilft oder diesen beeinflusst. Dieser Pseudozufallszahlengenerator (PRNG) erzeugt Bytes, die wie gewöhnliche Entropie aussehen; die Implementierung bot jedoch keine kryptografische Unvorhersehbarkeit. Die effektiv zu durchsuchenden Räume umfassten bei einer nominellen Ausgabe von 128 Bit ungefähr 2 USD^{39}$ Kandidaten und bei einer nominellen Ausgabe von 256 Bit ungefähr 2 USD^{47}$ Kandidaten [3].
Diese kleineren Räume machten es möglich, mögliche Wiederherstellungsphrasen zu rekonstruieren, die zugehörigen Wallet-Adressen abzuleiten und sie mit öffentlich einsehbaren Blockchain-Aktivitäten abzugleichen. Ein Geheimnis konnte so rekonstruiert werden, ohne etwas vom Gerät des Opfers zu extrahieren. Die Einhaltung des Standards für mnemonische Phrasen konnte den schwachen Zufall, der von der älteren Abhängigkeit übernommen wurde, nicht ausgleichen.
2,2 Coldcard: Ein Hardware-Zufallszahlengenerator, den der Code nicht nutzte
Coldcard zeigt, warum eine sichere Zufallsquelle allein nicht ausreicht, wenn die Anwendung einen anderen Generator aufruft. Obwohl das Gerät über einen Hardware-Zufallszahlengenerator verfügte, führte ein Integrationsfehler beim Build dazu, dass rng_get() im Pfad zur Seed-Erzeugung stattdessen auf Yasmarang, den Software-PRNG von MicroPython, verwies. Dieser nicht kryptografische PRNG wurde mit der festen eindeutigen ID des Geräts und begrenzten Zeitinformationen initialisiert. Dadurch war sein Anfangszustand hinreichend vorhersehbar, um die effektive Entropie der erzeugten Wallet-Seeds drastisch zu verringern [5].

Die Routine zur Seed-Erzeugung bezog außerdem einen zweiten Yasmarang-Generator ein. Bei älteren Mk2/Mk3-Geräten ging dieser zweite Generator von öffentlich bekannten Konstanten aus und steuerte keine zusätzliche Entropie bei. Bei neueren Modellen wurde zwar Zufälligkeit aus Secure Elements eingebracht, beim erneuten Initialisieren wurden jedoch nur 32 Bit beibehalten. Obwohl Wallet-Seeds mit 256 Bit erzeugt wurden, war der effektive Suchraum daher drastisch verkleinert. Coinkite schätzte unter den angegebenen Angriffsannahmen vorläufig etwa 2 USD^{40}$ Kandidaten für Mk2/Mk3 und 2 USD^{72}$ für Mk4/Q/Mk5 [6, 7].
Durch die Schwachstelle wurde die Wiederherstellung eines Seeds zu einer Offline-Suche: Ein Angreifer konnte aus möglichen Seeds Adressen ableiten und sie mit öffentlichen Blockchain-Daten vergleichen. Der praktische Aufwand hängt vom Modell und den Angriffsannahmen ab; aus der Schätzung von 2 USD^{72}$ folgt nicht dieselbe praktische Durchführbarkeit wie im Fall von 2 USD^{40}$. Bei einer Übereinstimmung werden die zugehörigen privaten Schlüssel offengelegt.
2.3 XRPH Wallet: Ein Fehler beim Eingabeformat, der den Schlüsselraum verkleinerte
Zum Erzeugungspfad gehört auch die Umwandlung der Zufallsausgabe in die von einer Wallet-API erwartete Eingabe. Bei XRPH Wallet ging durch diese Umwandlung der Großteil der erzeugten Eingabe verloren. Die Android-Anwendung erzeugte mit JavaScript Math.random() Blöcke aus Dezimalziffern, fügte sie zu einer Zeichenfolge zusammen und übergab diese an Wallet.fromEntropy(). Der empfangende Code interpretierte die Zeichen als kleine ganzzahlige Bytewerte und behielt nur die ersten 16 Positionen bei. Da zwei Positionen feste Leerzeichen als Trennzeichen enthielten, trugen nur 14 variable Dezimalziffern zur Entropie der resultierenden Wallet bei [8].
padlock = { A, B, C, D, E, F, G, H }; // each = 6 digits from the line above
r6 = A.join('') + ' ' + B.join('') + ' ' + C.join('') + ' ' + D.join('')
+ ' ' + E.join('') + ' ' + F.join('') + ' ' + G.join('') + ' ' + H.join('');
r5 = Wallet.fromEntropy;
r3 = r5.bind(Wallet)(r6); // a 55-char STRING is passed; fromEntropy wants 16 bytes
// compute entropy be like
const input = "528875 921568 528239 ..."; // decimal blocks
const entropy = Uint8Array.from(input).slice(0, 16);
// Result: [5,2,8,8,7,5,0,9,2,1,5,6,8,0,5,2]
Durch diese Umwandlung waren nur noch ungefähr 10 USD^{14}\approx 2^{46}$ Wallet-Eingaben erreichbar, statt des vorgesehenen Raums von etwa 2 USD^{128}$ bei gleichmäßig gezogener Entropie von 16 Byte. Diese Zahl beschreibt die unter der beobachteten Umwandlung erreichbaren Kandidaten, nicht einen kryptografischen Beweis für die statistische Entropie von Math.random().
Zwei Fehler verstärkten sich gegenseitig: eine ungeeignete Zufallsquelle und ein Fehler bei der Darstellung beziehungsweise Kodierung an der API-Schnittstelle. Beide können bei Funktionstests unentdeckt bleiben, weil die Wallet weiterhin plausibel aussehende Adressen erzeugt und gültige Transaktionen signiert. Die öffentliche Untersuchung belegt, dass sich Schlüssel aus dem verbliebenen Schlüsselraum wiederherstellen lassen; sie beweist für sich genommen nicht, auf welchem Weg der Angreifer an den Schlüssel gelangte.
2,4 Qubic Wallet: Schwache Zufälligkeit hinter einem Seed mit 55 Zeichen
Auch der Anfangszustand eines Generators kann die möglichen Seeds begrenzen, unabhängig davon, wie lang die ausgegebene Zeichenfolge erscheint. Qubic veranschaulicht dieses Problem: Die gemeldete Kompromittierung von Wallets betraf Seeds, die mit dem nicht kryptografischen Math.random() von JavaScript erzeugt wurden. Zu den betroffenen Umgebungen gehörten Apple-Browser und bestimmte ältere iOS-App-Builds auf Basis von JavaScriptCore [9, 10].
Die anfällige Erzeugungslogik und ihre Korrektur lassen sich wie folgt zusammenfassen [11]:
// Vulnerable seed generation (abridged)
seed += letters[Math.floor(Math.random() * 26)];
// Corrected approach (schematic excerpt of the fix)
crypto.getRandomValues(bytes);
if (byte < 234) seed += letters[byte % 26];
Math.random() 55-mal aufzurufen, liefert keine 55 unabhängigen Entropiequellen. Zwischen erneuten Initialisierungen verändert jeder PRNG-Aufruf seinen internen Zustand deterministisch. Für eine feste Aufrufposition gilt: Ist der anfängliche Seed , dann ist der gesamte Wallet-Seed mit 55 Zeichen eine deterministische Funktion . Die Kenntnis von und dieser Aufrufposition reicht aus, um alle 55 Zeichen zu reproduzieren; weitere PRNG-Aufrufe erzeugen keine zusätzliche Entropie.
Der Bereich möglicher Anfangszustände hängt von der Initialisierung durch die Laufzeitumgebung ab. Der am 29.10.2026 abgerufene JavaScriptCore-Quellcode-Snapshot initialisiert seinen PRNG mit einem Seed von 32 Bit. Daraus ergeben sich bei fester Aufrufposition höchstens 2 USD^{32}$ Sequenzen. Der hier untersuchte V8-Quellcode verwendet einen Seed von 64 Bit, woraus sich höchstens 2 USD^{64}$ solcher Sequenzen ergeben. Diese Obergrenzen gelten für die untersuchten Initialisierungspfade bei fester Aufrufposition. Aus den Snapshots gehen weder die genauen Browser-Builds hervor, die bei dem Vorfall verwendet wurden, noch der Aufwand, sie auszunutzen. Die Korrektur verwendet stattdessen crypto.getRandomValues(), um kryptografisch sichere Zufallswerte zu erhalten, und nutzt Rejection Sampling (byte < 234), um eine Verzerrung bei der Abbildung von Bytes auf 26 Buchstaben zu vermeiden [12, 13, 14].
3. Fehlerhaftes Signieren: Wiederherstellung privater Schlüssel aus öffentlichen Signaturen
Nachdem ein Schlüssel sicher erzeugt wurde, muss er auch bei seiner Verwendung zum Signieren geheim bleiben. Jede Signatur macht Beobachtern Daten zugänglich, und Implementierungsfehler können aus diesen öffentlichen Daten genügend Informationen für die Wiederherstellung des privaten Schlüssels machen. ECDSA und Schnorr verwenden für jede Signatur einen geheimen Skalar, eine sogenannte Nonce, um den Beitrag des privaten Schlüssels zur öffentlichen Signatur zu verschleiern.
Die Nonce muss geheim bleiben, darf unter demselben Schlüssel nicht für verschiedene Nachrichten wiederverwendet werden und muss die Verteilungsanforderungen des jeweiligen Verfahrens erfüllen. Eine deterministische Ableitung ist mit diesen Anforderungen vereinbar: Die Kenntnis des öffentlichen Schlüssels und der signierten Nachricht darf nicht ausreichen, um die Nonce vorherzusagen.
Als Beispiel dient die vereinfachte Schnorr-Beziehung:
wobei der private Schlüssel, die Nonce, eine aus öffentlichen Informationen (z. B. dem öffentlichen Schlüssel und der Nachricht) berechnete öffentliche Challenge, der öffentliche Signaturskalar und die Ordnung der Untergruppe ist. Eine bekannte Nonce legt unmittelbar offen, sofern invertierbar ist.
Zudem muss die Nonce nicht vollständig bekannt sein, damit der Schlüssel offengelegt werden kann. Einschränkungen oder Verzerrungen bei mehreren Nonces können genügend Informationen liefern, um den Schlüssel mit gitterbasierten Methoden wiederherzustellen. Ob dies praktikabel ist, hängt von den offengelegten Informationen und den verfügbaren Signaturen ab.
Die Tabelle unterscheidet die beiden in diesem Abschnitt untersuchten Nonce-Fehler: Bei Zilliqa waren die Nonces teilweise eingeschränkt, während die Nonces bei SecondFi anhand öffentlicher Daten berechenbar wurden. Die angegebenen Auswirkungen beziehen sich auf unterschiedliche historische Berichtszeiträume.
| Vorfall | Relevanter Zeitraum | Gemeldete Auswirkungen (ca.) | Nachstehend untersuchter Fehler |
|---|---|---|---|
| Zilliqa Ledger Wallet | März–Juli 2026 | 683.130.969,66 ZIL |
Verzerrte Signatur-Nonces bei EC-Schnorr |
| SecondFi | Juni 2026 | Durch die angeführten Codebelege nicht nachgewiesen | Fehlerhafte Ed25519-Nonce-Ableitung |
3,1 Zilliqa Ledger Wallet: 64 fehlende Bits in jeder Schnorr-Nonce
Beim Vorfall mit der Zilliqa Ledger Wallet lag ein Fehler in der Anwendung für ältere Zilliqa-Transaktionen mit EC-Schnorr vor [15]. Die Anwendung erzeugte Nonce-Material, kopierte jedoch den falschen Teil in ihren endgültigen Signaturpuffer. Sie behielt acht Bytes Null-Padding bei und verwarf acht Bytes tatsächlicher Zufallsdaten. Dadurch erfüllte jede betroffene Nonce 0 USD \le k < 2^{192},$ statt angemessen über die etwa 256-Bit-Gruppenordnung von secp256k1 verteilt zu sein.
Die Signaturgleichungen zeigen, warum die Einschränkung der Nonce von Bedeutung ist:
Dabei ist der Generator der Gruppe. Durch Umstellen erhält man
Jede Signatur liefert somit eine modulare Beziehung für das unbekannte , wobei die Nonce durch 2 USD^{192} begrenzt ist. Die Kombination mehrerer unabhängiger Beziehungen ergibt eine Instanz des Hidden Number Problem (HNP), die sich mittels Gitterreduktion angehen lässt. Laut dem offiziellen Untersuchungsbericht konnten private Schlüssel anhand von vier oder mehr betroffenen Signaturen rekonstruiert werden.
Das Secure Element musste die Bytes des privaten Schlüssels zu keinem Zeitpunkt preisgeben. Die verzerrten Nonces ermöglichten es, diesen Schlüssel aus bereits on-chain veröffentlichten Signaturen zu rekonstruieren.
3,2 SecondFi: Eine aus öffentlichen Daten berechenbare Signatur-Nonce
Bei SecondFi führte eine fehlerhafte Ed25519-Nonce-Ableitung zu mehr als einer teilweisen Einschränkung: Die Nonce wurde aus öffentlichen Daten berechenbar. Dadurch konnten private Signaturschlüssel aus einer einzigen öffentlich verfügbaren Transaktionssignatur rekonstruiert werden [16].
Bei einer Signatur nach dem Ed25519-Verfahren werden gemäß der vorgesehenen Konstruktion ein geheimer Skalar und ein privates Nonce-Präfix aus geheimem Schlüsselmaterial abgeleitet. Dabei ist der öffentliche Schlüssel, der Ed25519-Basispunkt, die signierte Nachricht und die Untergruppenordnung; bezeichnet SHA-512. Schematisch dargestellt:
Die fehlerhafte Implementierung setzt stattdessen . Wer die signierte Nachricht kennt, kann ableiten. Da , und öffentlich sind, kann ein Beobachter anschließend
berechnen, sofern modulo ungleich null ist.
Anders als bei Zilliqa, wo die Nonce nur teilweise preisgegeben wurde, genügte eine einzige betroffene Signatur, um den Signaturskalar zu rekonstruieren. Das beweist nicht automatisch, dass sich auch die ursprüngliche mnemonische Phrase oder sämtliche weiteren Schlüssel einer hierarchischen Wallet rekonstruieren lassen. Der Fehler lag an der Schnittstelle zwischen Schlüsselableitung und Signierung: Das erforderliche Geheimnis war verfügbar, wurde aber nie an die Routine zur Nonce-Ableitung übergeben.
4. Grundsätze für sichere Implementierung und Verifizierung
Zusammengenommen zeigen die Fälle, warum Zufallsquellen und Signaturalgorithmen gemeinsam mit dem Code geprüft werden müssen, der sie verbindet. Eine unvorhersagbare Quelle muss unvorhersagbare Schlüssel erzeugen, und diese Schlüssel müssen beim Signieren geheim bleiben. Fehler in Konvertierungsroutinen oder Bibliotheksschnittstellen können beide Anforderungen verletzen.
Die Abschnitte 4,1 und 4,2 legen die Grundsätze für Entwurf und Implementierung bei der Schlüsselgenerierung und Signierung dar. Abschnitt 4,3 erläutert, welche Belege Prüfungen und Tests liefern sollten, um die Einhaltung dieser Grundsätze im bereitgestellten System zu beurteilen.
4,1 Sicherheit bei der Schlüsselgenerierung bewahren
Aus den Fällen zur Schlüsselgenerierung ergeben sich drei Implementierungsanforderungen:
-
Kryptografisch sichere Zufallsdaten verwenden und bei einem Fehler abbrechen. Seeds und private Schlüssel benötigen eine geeignete kryptografisch sichere Quelle, etwa einen kryptografisch sicheren Pseudozufallszahlengenerator (CSPRNG). Ill Bloom und Qubic zeigen, warum ein universell einsetzbarer Generator diese Rolle nicht übernehmen kann. Ist die vorgesehene Quelle nicht verfügbar oder fällt sie aus, muss die Generierung abgebrochen werden, statt stillschweigend einen schwächeren Ersatz zu verwenden.
-
Entropie bei der Datenkonvertierung erhalten. Die Ausgabe einer sicheren Quelle muss die erforderliche Unvorhersagbarkeit bewahren, wenn sie codiert, daraus Werte gezogen oder sie zwischen Schnittstellen weitergegeben wird. Der Fall XRPH Wallet zeigt, warum eine gültig aussehende Ausgabe nicht ausreicht. Vorgaben für Typ, Länge und Codierung müssen verhindern, dass unbeabsichtigtes Abschneiden oder verzerrte Zuordnungen den effektiven Schlüsselraum verkleinern.
-
Sicherstellen, dass der bereitgestellte Code die vorgesehene Quelle nutzt. Coldcard zeigt, dass das Vorhandensein einer sicheren Zufallsquelle nicht belegt, welche Quelle die Anwendung tatsächlich aufruft. Die Auswahl der Quelle muss bei Integration, Kompilierung und Bereitstellung korrekt bleiben, auch auf Fehler- und Ausweichpfaden. Eine Entwurfsannahme über den RNG muss für die ausführbare Datei gelten, die auf der Zielplattform läuft.
4,2 Geheimhaltung beim Signieren bewahren
Die Anforderungen an die Generierung schützen die Erstellung eines Schlüssels. Ihn während der Verwendung geheim zu halten, erfordert außerdem einen korrekten Umgang mit Nonces. Die Anforderungen hängen vom jeweiligen Verfahren ab; die Liste umfasst neben den in den Fällen untersuchten Verfahren Schnorr und Ed25519 auch ECDSA.
-
ECDSA: Nonces müssen geheim und unvorhersagbar bleiben und dürfen bei unterschiedlichen Nachrichten unter demselben Schlüssel nicht wiederverwendet werden. Eine deterministische Generierung gemäß RFC 6979 [17] vermeidet die Abhängigkeit von neuen externen Zufallsdaten für jede Signatur. Implementierungen benötigen dennoch Schutz vor der Preisgabe von Informationen über Seitenkanäle und vor Fehlerangriffen.
-
EdDSA: Alle für die Nonce-Ableitung erforderlichen geheimen Eingaben müssen erhalten bleiben. SecondFi zeigt, welche Folgen es hat, das private Präfix wegzulassen und ausschließlich öffentliche Daten zu verwenden. Wrapper und Schlüsseladapter müssen die vollständigen, nach RFC 8032 [18] erforderlichen geheimen Eingaben übergeben, statt eine funktionierende Signatur als Beleg für korrekte Eingaben zu betrachten.
-
Schnorr: Die vom Verfahren geforderte Verteilung und Darstellung der Nonces müssen erhalten bleiben. Wie Zilliqa zeigt, reicht es nicht aus, Wiederholungen und vollständig vorhersagbare Nonces zu vermeiden, wenn ein Teil der Zufallsdaten verloren geht. Datenverarbeitung und Skalarkonvertierung dürfen keine ausnutzbaren Einschränkungen oder Verzerrungen einführen.
Gründlich geprüfte Bibliotheken verringern das Implementierungsrisiko, beseitigen aber keine Integrationsfehler. Selbst ein korrektes Signaturverfahren bleibt unsicher, wenn der aufrufende Code unvollständige oder beschädigte Eingaben übergibt.
4.3 Sicherheitseigenschaften testen
Um zu beurteilen, ob diese Anforderungen erfüllt sind, müssen Prüfungen die Eingaben durch die tatsächlich ausgeführte Implementierung verfolgen. Eine gültige Ausgabe kann einen Integrationsfehler verbergen. Daher muss die Verifizierung auch Pfade abdecken, die bei gewöhnlichen Funktionstests übersehen werden. Die Tabelle überführt die Anforderungen an Generierung und Signierung in konkrete Prüfziele:
| Prüfbereich | Verifizierungsziel |
|---|---|
| Unvorhersagbarkeit der Entropie | Feststellen, ob Quelle, Initialisierung und effektiver Seed-Raum einer praktisch durchführbaren Vorhersage oder vollständigen Durchsuchung widerstehen |
| Erhalt der Entropie | Verifizieren, dass Konvertierung und Stichprobenziehung die erforderliche Unvorhersagbarkeit ohne unbeabsichtigtes Abschneiden oder Verzerrungen bewahren |
| RNG-Integration | Bestätigen, dass die bereitgestellte ausführbare Datei die vorgesehene Quelle nutzt, auch auf Fehler- und Ausweichpfaden |
| Geheimhaltung der Nonces | Verifizieren, dass bei der Nonce-Generierung oder -Ableitung die Geheimhaltung einschließlich aller erforderlichen geheimen Eingaben gewahrt bleibt und die Nonce nicht allein aus öffentlichen Daten reproduziert werden kann |
| Korrektheit der Nonces | Den Umgang mit Nonces mit den Anforderungen des Verfahrens vergleichen und dabei gegebenenfalls Tests mit bekannten Soll-Ergebnissen sowie unabhängige Implementierungen heranziehen |
| Sicherheit der Abhängigkeiten | Die Versionen und Integration kryptografischer Abhängigkeiten prüfen und kontrollieren, dass Aktualisierungen das erforderliche Verhalten bewahren |
Zur Beurteilung dieser Ziele müssen mehrere Methoden kombiniert werden. Bei der Codeprüfung wird nachverfolgt, wie geheime Eingaben und Zufallsdaten die bereitgestellten Routinen zur Generierung und Signierung erreichen. Tests für Fehlerpfade und Fehlerinjektion untersuchen das Verhalten, wenn gewöhnliche Annahmen nicht gelten; Tests mit bekannten Soll-Ergebnissen und Vergleiche mit unabhängigen Implementierungen können Abweichungen vom Verfahren aufdecken. Statistische Tests können offensichtliche Verzerrungen erkennen. Doch weder die erfolgreiche Adressgenerierung noch die Signaturverifizierung oder statistische Tests allein können kryptografische Sicherheit belegen. Die gesammelten Belege müssen anhand der Anforderungen an Quelle, Eingabeverarbeitung und Verfahren beurteilt werden.
Externe Sicherheitsteams oder Fachleute können die interne Verifizierung durch Code- und Integrationsaudits ergänzen, insbesondere an den Schnittstellen zwischen Zufallsquellen, Schlüsselableitung und Signaturbibliotheken. Der Prüfungsumfang sollte Versionen von Abhängigkeiten, die Build-Konfiguration und den ausgeführten Codepfad abdecken. Befunde sollten die betroffene Sicherheitseigenschaft benennen und reproduzierbare Belege sowie Regressionstests liefern. Änderungen an der Implementierung oder ihren Abhängigkeiten müssen weiterhin verifiziert werden.
Führender Sicherheitsauditor für Web3
Entwurf, Code und Geschäftslogik vor dem Start prüfen
5. Fazit
Die sechs Vorfälle zeigen zwei Wege, auf denen Implementierungsfehler geschützte Schlüssel gefährden können: indem sie bei der Generierung den Raum möglicher Schlüssel verkleinern oder durch Signaturen Informationen über einen bestehenden Schlüssel preisgeben. Aus der Analyse dieser Fehler ergeben sich Anforderungen an Generierung und Signierung sowie Prüf- und Testziele für den in der Zahlungsinfrastruktur bereitgestellten Code.
Für Zahlungsinstitute schützt die sichere Speicherung das gespeicherte Geheimnis; sie kann weder eine vorhersagbare Generierung noch durch das Signieren preisgegebene Informationen ausgleichen. Die erforderlichen Eigenschaften müssen auch bei Abhängigkeiten, Adaptern und der Bereitstellung erhalten bleiben. Prüfungen und Tests müssen diese vollständige Implementierung untersuchen, statt aus gültigen Adressen und Signaturen auf Sicherheit zu schließen.
Diese Implementierungsanforderungen ergänzen die in Teil 1 von Beyond Secure Storage untersuchten Kontrollen im Arbeitsablauf. Teil 1 behandelt Risiken im Arbeitsablauf, vorbeugende Prüfungen und die Begrenzung von Verlusten, wenn diese Prüfungen unbefugte Vorgänge nicht verhindern. Teil 2 befasst sich mit Implementierungsfehlern, die einem Angreifer ermöglichen können, eigenständig Signaturen zu erstellen. Eine korrekte kryptografische Ausführung belegt keine geschäftliche Autorisierung; eine gültige geschäftliche Genehmigung belegt nicht, dass der Signaturschlüssel unvorhersagbar ist oder nicht rekonstruiert werden kann. Sichere Zahlungs- und Signatursysteme erfordern, dass sowohl der Autorisierungsablauf als auch die zugrunde liegende kryptografische Implementierung entworfen und verifiziert werden.
Quellen
-
[1] BIP-39, Mnemonischer Code zur Generierung deterministischer Schlüssel.
-
[2] BIP-32, Hierarchisch-deterministische Wallets.
-
[3] CryptoJS, Sicherheitshinweis GHSA-rg76-677x-56q9.
-
[4] CryptoJS, Quellcode von core.js, Version 3.1.9-1.
-
[5] Coldcard, Firmware-Sicherheitshinweis und Versionshinweise.
-
[6] MicroPython, Coldcard-Untersuchungsbericht aus der Sicht von MicroPython.
-
[7] Coinkite, Technische Detailanalyse des Entropieproblems.
-
[8] XRPL.to, Der Angriff auf XRPH Wallet: 4011 Wallets geleert, und jeder Schlüssel war erratbar.
-
[9] Qubic, Stellungnahme zum Vorfall und Hinweise für betroffene Plattformen.
-
[10] Qubicmap, Chronologie des Qubic-Vorfalls und Zusammenfassung zu den Wallets.
-
[11] Qubic Wallet, Korrektur der sicheren Seed-Generierung 09dd288.
-
[12] WebKit, JSGlobalObject.cpp, Initialisierung von m_weakRandom.
-
[13] WebKit, WeakRandom.h, Seed- und PRNG-Implementierung.
-
[15] Zilliqa, Untersuchungsbericht: Verzerrung der Nonces beim älteren Schnorr-Verfahren.
-
[16] KarpelesLab, Analyse und Reproduktion der SecondFi-Implementierung.
-
[17] RFC 6979, Deterministische Verwendung von DSA und ECDSA.
-
[18] RFC 8032, Digitaler Signaturalgorithmus auf Edwards-Kurven (EdDSA).



