Lass uns ein bisschen Computerpoker spielen, nur du, ich und ein Server, dem wir beide vertrauen. Der Server verwendet einen Pseudozufallszahlengenerator, der unmittelbar vor dem Spielen mit einem 32-Bit-Startwert initialisiert wird. Es gibt also ungefähr vier Milliarden mögliche Decks.
Ich habe fünf Karten auf der Hand - anscheinend spielen wir nicht Texas Hold'em. Angenommen, die Karten werden mir, Ihnen, mir, Ihnen usw. ausgeteilt. Ich habe also die erste, dritte, fünfte, siebte und neunte Karte im Stapel.
Früher habe ich den Pseudozufallszahlengenerator vier Milliarden Mal mit jedem Startwert ausgeführt und die jeweils erste erzeugte Karte in eine Datenbank geschrieben. Angenommen, meine erste Karte ist die Pik Dame. Das zeigt nur eine von 52 möglichen Decks als erste Karte. Daher haben wir die möglichen Decks von vier Milliarden auf ungefähr 80 Millionen reduziert.
Angenommen, meine zweite Karte besteht aus drei Herzen. Jetzt führe ich meinen RNG noch 80 Millionen Mal aus und benutze dabei die 80 Millionen Samen, aus denen die Pik Dame als erste Zahl hervorgeht. Das dauert ein paar Sekunden. Ich schreibe alle Stapel, aus denen die drei Herzen hervorgehen, als dritte Karte auf - die zweite Karte in meiner Hand. Das sind wieder nur etwa 2% der Decks, und jetzt sind es nur noch 2 Millionen Decks.
Angenommen, die dritte Karte in meiner Hand ist die 7 der Vereine. Ich habe eine Datenbank mit 2 Millionen Samen, die meine beiden Karten austeilen. Ich führe meine RNG weitere 2 Millionen Mal aus, um die 2% der Decks zu finden, aus denen die 7 der Clubs als dritte Karte hervorgehen, und wir haben nur noch 40.000 Decks.
Sie sehen, wie das geht. Ich führe meinen RNG 40000 mehrmals aus, um alle Samen zu finden, aus denen meine vierte Karte hervorgeht, und das bringt uns auf 800 Kartendecks. Dann führe ich den RNG 40000 mehrmals aus, um die ~ 20 Samen zu erhalten, aus denen meine fünfte Karte hervorgeht, und jetzt nur noch Generiere diese zwanzig Kartenspiele und ich weiß, dass du eine von zwanzig möglichen Händen hast. Außerdem habe ich eine sehr gute Vorstellung davon, was ich als nächstes zeichnen werde.
Sehen Sie jetzt, warum echte Zufälligkeit wichtig ist? So wie Sie es beschreiben, denken Sie, dass Verteilung wichtig ist, aber Verteilung ist nicht das, was einen Prozess zufällig macht. Unvorhersehbarkeit macht einen Prozess zufällig.
AKTUALISIEREN
Basierend auf den (aufgrund ihrer unkonstruktiven Natur jetzt gelöschten) Kommentaren sind mindestens 0,3% der Leute, die dies gelesen haben, in Bezug auf meinen Punkt verwirrt. Wenn Leute gegen Punkte argumentieren, die ich nicht gemacht habe, oder noch schlimmer, für Punkte argumentieren , die ich gemacht habe , unter der Annahme, dass ich sie nicht gemacht habe, dann weiß ich, dass ich klarer und sorgfältiger erklären muss.
Es scheint eine besondere Verwirrung um die Wortverteilung zu geben , daher möchte ich die Verwendung sorgfältig herausstellen.
Die anstehenden Fragen sind:
- Wie unterscheiden sich Pseudozufallszahlen von echten Zufallszahlen?
- Warum ist der Unterschied wichtig?
- Haben die Unterschiede etwas mit der Verteilung der PRNG-Ausgabe zu tun?
Betrachten wir zunächst den perfekten Weg, um ein zufälliges Kartenspiel zu generieren, mit dem Sie Poker spielen können. Dann werden wir sehen, wie andere Techniken zum Erzeugen von Decks unterschiedlich sind und ob es möglich ist, diesen Unterschied auszunutzen.
Beginnen wir mit der Annahme, dass wir eine magische Schachtel haben, die beschriftet ist TRNG
. Als Eingabe geben wir ihm eine ganze Zahl n, die größer oder gleich eins ist, und als Ausgabe gibt es uns eine echte Zufallszahl zwischen eins und n, einschließlich. Die Ausgabe der Box ist völlig unvorhersehbar (wenn eine andere Zahl als eins angegeben wird) und jede Zahl zwischen eins und n ist genauso wahrscheinlich wie eine andere. das heißt, die Verteilung ist gleichmäßig . (Es gibt andere fortgeschrittenere statistische Überprüfungen der Zufälligkeit, die wir durchführen könnten. Ich ignoriere diesen Punkt, da er für meine Argumentation nicht relevant ist. TRNG ist statistisch gesehen vollkommen zufällig.)
Wir beginnen mit einem nicht gemischten Kartenspiel. Wir bitten die Box um eine Zahl zwischen eins und 52 - das heißt TRNG(52)
,. Unabhängig von der Zahl, die es zurückgibt, zählen wir so viele Karten von unserem sortierten Stapel ab und entfernen diese Karte. Es wird die erste Karte im gemischten Deck. Dann bitten wir um TRNG(51)
und tun dasselbe, um die zweite Karte auszuwählen und so weiter.
Eine andere Sichtweise ist: Es gibt 52! = 52 x 51 x 50 ... x 2 x 1 mögliche Decks, das sind ungefähr 2 226 . Wir haben einen von ihnen wirklich zufällig ausgewählt.
Jetzt geben wir die Karten aus. Wenn ich mir meine Karten ansehe, habe ich keine Ahnung, welche Karten Sie haben. (Abgesehen von der offensichtlichen Tatsache, dass Sie keine der Karten haben, die ich habe.) Es können alle Karten sein, mit gleicher Wahrscheinlichkeit.
Lassen Sie mich also sicherstellen, dass ich dies klar erkläre. Wir haben eine gleichmäßige Verteilung jedes einzelnen Outputs von TRNG(n)
; Jeder wählt eine Zahl zwischen 1 und n mit einer Wahrscheinlichkeit von 1 / n. Das Ergebnis dieses Prozesses ist, dass wir eines von 52 ausgewählt haben! möglich Decks mit einer Wahrscheinlichkeit von 1/52 !, so die Verteilung über die Menge der möglichen Decks sind auch einheitlich.
Gut.
Nehmen wir nun an, wir haben eine weniger magische Box mit der Bezeichnung PRNG
. Bevor Sie es verwenden können, müssen sie werden ausgesät mit einem 32-Bit - Zahl ohne Vorzeichen.
ASIDE: Warum 32 ? Könnte es nicht mit einer 64- oder 256- oder 10000-Bit-Zahl geimpft werden? Sicher. Aber (1) in der Praxis werden die meisten handelsüblichen PRNGs mit einer 32-Bit-Zahl geimpft, und (2) wenn Sie 10000 zufällige Bits haben, um den Keim zu bilden, warum verwenden Sie dann überhaupt einen PRNG? Sie haben bereits eine Quelle von 10000 Zufälligkeiten!
Wie auch immer, zurück zur Funktionsweise des PRNG: Nachdem es ausgesät wurde, können Sie es genauso verwenden, wie Sie es verwenden TRNG
. Das heißt, Sie übergeben ihm eine Zahl, n, und es gibt Ihnen eine Zahl zwischen 1 und n, einschließlich, zurück. Darüber hinaus ist die Verteilung dieser Ausgabe mehr oder weniger gleichmäßig . Das heißt, wenn wir PRNG
nach einer Zahl zwischen 1 und 6 fragen , erhalten wir ungefähr jeweils ein Sechstel der Zeit 1, 2, 3, 4, 5 oder 6, unabhängig davon, um welchen Samen es sich handelt.
Ich möchte diesen Punkt mehrmals hervorheben, da er einige Kommentatoren verwirrt. Die Verteilung des PRNG ist auf mindestens zwei Arten gleichmäßig. Nehmen wir zunächst an, wir wählen einen bestimmten Samen. Wir würden erwarten , dass die Sequenz PRNG(6), PRNG(6), PRNG(6)...
eine Million mal eine gleichmäßige Verteilung von Zahlen zwischen 1 erzeugen würde und 6. Und zweitens, wenn wir eine Million verschiedene Samen gewählt und rief PRNG(6)
einmal für jeden Samen, wieder würden wir eine gleichmäßige Verteilung von Zahlen erwarten von 1 bis 6. Die Gleichförmigkeit des PRNG über beide dieser Operationen hinweg ist für den Angriff, den ich beschreibe, nicht relevant .
Dieser Prozess wird als pseudozufällig bezeichnet, da das Verhalten der Box tatsächlich vollständig deterministisch ist. es wählt aus 2 32 möglichen Verhaltensweisen basierend auf dem Samen aus. Das heißt, sobald es ausgesät ist, PRNG(6), PRNG(6), PRNG(6), ...
wird eine Folge von Zahlen mit einer gleichmäßigen Verteilung erzeugt, aber diese Folge wird vollständig durch den Samen bestimmt. Für eine bestimmte Folge von Aufrufen, z. B. PRNG (52), PRNG (51) usw., gibt es nur 2 32 mögliche Folgen. Der Same entscheidet im Wesentlichen, welchen wir bekommen.
Um ein Deck zu generieren, generiert der Server jetzt einen Seed. (Wie? Wir kommen wieder zu diesem Punkt.) Dann rufen sie PRNG(52)
, PRNG(51)
und so auf das Deck, ähnlich wie vor zu erzeugen.
Dieses System ist anfällig für den von mir beschriebenen Angriff. Um den Server anzugreifen, müssen wir zuerst unsere eigene Kopie der Box mit 0 ausstatten und danach fragen PRNG(52)
und notieren. Dann setzen wir wieder 1 ein, fragen nach PRNG(52)
und schreiben dies auf bis zu 2 32 -1.
Jetzt muss der Pokerserver, der PRNG verwendet, um Decks zu generieren, irgendwie einen Startwert generieren. Es spielt keine Rolle, wie sie das tun. Sie könnten anrufen TRNG(2^32)
, um einen wirklich zufälligen Samen zu bekommen. Oder sie könnten die aktuelle Zeit als einen Samen nehmen, der überhaupt kaum zufällig ist; Ich weiß genau wie Sie, wie spät es ist. Der Punkt meines Angriffs ist, dass es keine Rolle spielt, weil ich meine Datenbank habe . Wenn ich meine erste Karte sehe, kann ich 98% der möglichen Samen eliminieren. Wenn ich meine zweite Karte sehe, kann ich 98% mehr eliminieren und so weiter, bis ich schließlich zu einer Handvoll möglicher Samen komme und mit hoher Wahrscheinlichkeit weiß, was in Ihrer Hand ist.
Ich möchte noch einmal betonen, dass wirPRNG(6)
hier davon ausgehen, dass wir , wenn wir eine Million Mal anrufen würden, jede Zahl ungefähr ein Sechstel der Zeit erhalten würden . Diese Verteilung ist (mehr oder weniger) gleichmäßig , und wenn Sie sich nur für die Gleichmäßigkeit dieser Verteilung interessieren , ist das in Ordnung. Der Punkt der Frage war, ob es noch andere Dinge gibt PRNG(6)
, die uns interessieren? und die antwort ist ja . Uns liegt auch die Unvorhersehbarkeit am Herzen.
Eine andere Möglichkeit, das Problem zu betrachten, besteht darin, dass die Verteilung von einer Million Anrufen PRNG(6)
möglicherweise in Ordnung ist, da der PRNG aus nur 2 32 möglichen Verhaltensweisen auswählt , jedoch nicht jedes mögliche Deck generieren kann. Es können nur 2 32 der 2 226 möglichen Decks generiert werden . ein winziger Bruchteil. Die Verteilung auf alle Decks ist also sehr schlecht. Aber auch hier beruht der grundlegende Angriff darauf, dass wir das vergangene und zukünftige Verhalten einer kleinen Stichprobe ihrer Ergebnisse erfolgreich vorhersagen könnenPRNG
.
Lassen Sie mich dies ein drittes oder viermal sagen, um sicherzustellen, dass dies eintritt. Hier gibt es drei Verteilungen. Erstens die Verteilung des Prozesses, der den zufälligen 32-Bit-Startwert erzeugt. Das kann vollkommen zufällig, unvorhersehbar und einheitlich sein und der Angriff wird immer noch funktionieren . Zweitens, die Verteilung von einer Million Anrufen an PRNG(6)
. Das kann vollkommen gleichmäßig sein und der Angriff wird immer noch funktionieren. Drittens die Verteilung der Decks, die nach dem von mir beschriebenen Pseudozufallsprozeß ausgewählt wurden. Diese Verteilung ist extrem schlecht; nur ein winziger Bruchteil der möglichen IRL-Decks kann möglicherweise ausgewählt werden. Der Angriff hängt von der Vorhersagbarkeit des Verhaltens des PRNG ab, basierend auf der teilweisen Kenntnis seines Outputs .
ASIDE: Für diesen Angriff muss der Angreifer den genauen vom PRNG verwendeten Algorithmus kennen oder erraten können. Ob das realistisch ist oder nicht, ist eine offene Frage. Allerdings , wenn ein Sicherheitssystem entwerfen Sie entwerfen müssen sie sicher vor Angriffen sein , auch wenn der Angreifer alle Algorithmen im Programm kennt . Anders ausgedrückt: Der Teil eines Sicherheitssystems, der geheim bleiben muss, damit das System sicher ist, wird als "Schlüssel" bezeichnet. Wenn Ihr System aus Sicherheitsgründen davon abhängt, dass die von Ihnen verwendeten Algorithmen geheim sind, enthält Ihr Schlüssel diese Algorithmen . Das ist eine extrem schwache Position!
Weitermachen.
Nehmen wir nun an, wir haben eine dritte beschriftete magische Kiste CPRNG
. Es ist eine Krypto-Version von PRNG
. Es wird ein 256-Bit-Startwert anstelle eines 32-Bit-Startwerts benötigt. Es teilt sich PRNG
die Eigenschaft, die der Startwert aus 2 256 möglichen Verhaltensweisen auswählt . Und wie bei unseren anderen Maschinen hat es die Eigenschaft, dass eine große Anzahl von Aufrufen zu CPRNG(n)
einer gleichmäßigen Verteilung der Ergebnisse zwischen 1 und n führt: jede geschieht 1 / n der Zeit. Können wir unseren Angriff dagegen führen?
Unser ursprünglicher Angriff erfordert, dass wir 2 32 Zuordnungen von Samen zu speichern PRNG(52)
. 2 256 ist jedoch eine viel größere Zahl; Es ist völlig unmöglich CPRNG(52)
, so oft auszuführen und die Ergebnisse zu speichern.
Angenommen, es gibt einen anderen Weg, um den Wert des CPRNG(52)
Samens zu ermitteln und daraus eine Tatsache abzuleiten. Wir waren bisher ziemlich dumm und haben alle möglichen Kombinationen brachial erzwungen. Können wir in die magische Kiste schauen, herausfinden, wie sie funktioniert, und anhand der Ausgabe Fakten über den Samen ableiten?
Nein . Die Details sind zu kompliziert zu erklären, aber CPRNGs sind geschickt so konstruiert, dass es unmöglich ist , abzuleiten , jede nützliche Tatsache über die Samen aus dem ersten Ausgang CPRNG(52)
oder von jeder Teilmenge des Ausgangs, egal wie groß .
Angenommen, der Server CPRNG
generiert jetzt Decks. Es benötigt einen 256-Bit-Startwert. Wie wählt es diesen Samen aus? Wenn es einen Wert wählt, den ein Angreifer vorhersagen kann, wird der Angriff plötzlich wieder realisierbar . Wenn wir feststellen können, dass von den 2 256 möglichen Startwerten wahrscheinlich nur vier Milliarden vom Server ausgewählt werden, sind wir wieder im Geschäft . Wir können diesen Angriff erneut starten, wobei wir nur auf die geringe Anzahl von Samen achten, die möglicherweise erzeugt werden können.
Der Server sollte daher sicherstellen, dass die 256-Bit-Zahl gleichmäßig verteilt ist, dh, jeder mögliche Startwert wird mit einer Wahrscheinlichkeit von 1/2 256 ausgewählt . Grundsätzlich sollte der Server anrufen TRNG(2^256)-1
, um den Startwert für zu generieren CPRNG
.
Was ist, wenn ich den Server hacken und in ihn hineinsehen kann, um zu sehen, welcher Startwert ausgewählt wurde? In diesem Fall kennt der Angreifer die gesamte Vergangenheit und Zukunft des CPRNG . Der Autor des Servers muss sich vor diesem Angriff schützen! (Wenn ich diesen Angriff erfolgreich ausführen kann, kann ich das Geld wahrscheinlich auch direkt auf mein Bankkonto überweisen. Das ist also vielleicht nicht so interessant. Der Punkt ist: Der Keim muss ein schwer zu erratendes Geheimnis sein, und a wirklich zufällige 256-Bit-Zahl ist verdammt schwer zu erraten.)
Zurück zu meinem früheren Punkt über die Tiefenverteidigung: Der 256-Bit-Startwert ist der Schlüssel für dieses Sicherheitssystem. Die Idee eines CPRNG ist, dass das System sicher ist, solange der Schlüssel sicher ist . Selbst wenn jede andere Tatsache über den Algorithmus bekannt ist, sind die Karten des Gegners unvorhersehbar, solange Sie den Schlüssel geheim halten können.
OK, also sollte der Samen sowohl geheim als auch gleichmäßig verteilt sein, denn wenn dies nicht der Fall ist, können wir einen Angriff starten. Wir gehen davon aus, dass die Verteilung der Outputs von CPRNG(n)
gleichmäßig ist. Was ist mit der Aufteilung auf alle möglichen Decks?
Sie könnten sagen: Es gibt 2 256 mögliche Sequenzen, die vom CPRNG ausgegeben werden, aber es gibt nur 2 226 mögliche Decks. Daher gibt es mehr mögliche Sequenzen als Decks. In diesem System ist jetzt (mit hoher Wahrscheinlichkeit) jedes mögliche IRL-Deck möglich. Und das ist ein gutes Argument, außer ...
2 226 ist nur eine Annäherung an 52 !. Teilen Sie es aus. 2 256/52 ! kann unmöglich eine ganze Zahl sein, weil zum einen 52! ist durch 3 teilbar, aber keine Potenz von zwei ist! Da dies jetzt keine ganze Zahl ist, haben wir die Situation, in der alle Decks möglich sind , aber einige Decks sind wahrscheinlicher als andere .
Wenn das nicht klar ist, betrachten Sie die Situation mit kleineren Zahlen. Angenommen, wir haben drei Karten, A, B und C. Angenommen, wir verwenden ein PRNG mit einem 8-Bit-Startwert, sodass 256 mögliche Startwerte vorhanden sind. Es gibt 256 mögliche Ausgaben, PRNG(3)
abhängig von der Saat; Es gibt keine Möglichkeit, ein Drittel von ihnen A, ein Drittel von ihnen B und ein Drittel von ihnen C zu haben, da 256 nicht gleichmäßig durch 3 teilbar ist. Es muss eine geringe Tendenz zu einem von ihnen bestehen.
In ähnlicher Weise teilt sich 52 nicht gleichmäßig in 2 256 , so dass es eine gewisse Neigung zu einigen Karten als der zuerst gewählten Karte und eine Neigung zu anderen geben muss.
In unserem ursprünglichen System mit einem 32-Bit-Startwert gab es eine massive Verzerrung, und die große Mehrheit der möglichen Decks wurde nie produziert. In diesem System können alle Decks produziert werden, aber die Verteilung der Decks ist immer noch fehlerhaft . Einige Decks sind etwas wahrscheinlicher als andere.
Die Frage ist nun: Haben wir einen Angriff, der auf diesem Fehler beruht? und die Antwort ist in der Praxis wahrscheinlich nicht . CPRNGs sind so ausgelegt, dass , wenn die Samen wirklich zufällig ist dann es rechnerisch unmöglich ist , den Unterschied zwischen zu sagen , CPRNG
und TRNG
.
OK, also lassen Sie uns zusammenfassen.
Wie unterscheiden sich Pseudozufallszahlen von echten Zufallszahlen?
Sie unterscheiden sich in der Berechenbarkeit, die sie aufweisen.
- Wirklich zufällige Zahlen sind nicht vorhersehbar.
- Alle Pseudozufallszahlen sind vorhersehbar, wenn der Keim bestimmt oder erraten werden kann.
Warum ist der Unterschied wichtig?
Weil es Anwendungen gibt, bei denen die Sicherheit des Systems auf Unvorhersehbarkeit beruht .
- Wenn eine TRNG zur Auswahl jeder Karte verwendet wird, ist das System nicht verfügbar.
- Wenn eine CPRNG verwendet wird, um jede Karte auszuwählen, ist das System sicher, wenn der Startwert sowohl unvorhersehbar als auch unbekannt ist.
- Wenn ein gewöhnliches PRNG mit einem kleinen Saatgutraum verwendet wird, ist das System nicht sicher, unabhängig davon, ob das Saatgut unvorhersehbar oder unbekannt ist. Ein ausreichend kleiner Saatraum ist anfällig für Brute-Force-Angriffe der von mir beschriebenen Art.
Hat der Unterschied etwas mit der Verteilung der PRNG-Ausgabe zu tun?
Die Gleichmäßigkeit der Verteilung oder deren Fehlen für einzelne Anrufe zu RNG(n)
ist nicht relevant für die Angriffe ich beschrieben habe.
Wie wir gesehen haben, ergibt sich sowohl eine PRNG
als auch CPRNG
eine schlechte Verteilung der Wahrscheinlichkeit, ein einzelnes Deck aller möglichen Decks zu wählen. Das PRNG
ist erheblich schlimmer, aber beide haben Probleme.
Noch eine Frage:
Wenn TRNG so viel besser ist als CPRNG, was wiederum so viel besser ist als PRNG, warum verwendet jemand CPRNG oder PRNG?
Zwei Gründe.
Erstens: Aufwand. TRNG ist teuer . Es ist schwierig, wirklich Zufallszahlen zu generieren. CPRNGs liefern gute Ergebnisse für beliebig viele Anrufe mit nur einem Anruf bei TRNG für den Startwert. Der Nachteil ist natürlich, dass Sie diesen Samen geheim halten müssen .
Zweitens: Manchmal wollen wir Berechenbarkeit, und alles, was uns wichtig ist, ist eine gute Verteilung. Wenn Sie "zufällige" Daten als Programmeingaben für eine Testsuite generieren und ein Fehler auftritt, ist es schön, wenn die Testsuite erneut ausgeführt wird und der Fehler erneut auftritt!
Ich hoffe das ist jetzt viel klarer.
Wenn Ihnen das gefallen hat, können Sie vielleicht weitere Informationen zum Thema Zufälligkeit und Permutationen lesen: