2015-05-27 1 views
6

Ich brauche kryptografisch sichere Zufallsdaten in C++ 11 und ich bin besorgt, dass die Verwendung von random_device für alle Daten die Leistung stark einschränken würde (Siehe Folie 23 von Stephan T. Lavavejs "rand() Considered Harmful", wo er sagt, dass wenn er getestet (auf seinem System), war random_device 1,93 MB/s und mt19937 war 499 MB/s, da dieser Code auf mobilen Geräten (Android über JNI und iOS) laufen wird, die wahrscheinlich langsamer als die oben genannten Zahlen sind.Kann ich kryptografisch sichere Zufallsdaten aus einer Kombination von random_device und mt19937 mit Neuansätzen erzeugen?

Außerdem ist mir bekannt, dass mt19937 nicht kryptographisch sicher ist, von wikipedia: "Beobachten einer ausreichenden Anzahl von Iterationen (624 im Fall von MT19937, da dies die Größe des Zustandsvektors ist, aus dem zukünftige Iterationen erzeugt werden) erlaubt es, alle zukünftigen Iterationen vorherzusagen ".

Unter Berücksichtigung aller oben genannten Informationen kann ich kryptografisch sichere Zufallsdaten generieren, indem ich alle 624 Iterationen von mt19937? Oder (möglicherweise) noch besser, jede X-Iteration, bei der X eine Zufallszahl ist (von random_device oder mt19937, die von random_device gesetzt wird) zwischen 1 und 624?

+1

'random_device' ist nicht einmal erforderlich, um nichtdeterministisch zu sein, also würde ich denken, das ist keine sehr gute Idee. Wenn Sie wirklich nicht-deterministische Daten benötigen, ist die Verwendung der Krypto-API, die das Betriebssystem anbietet, wahrscheinlich der richtige Weg. – Praetorian

+0

@Praetorian Auf iOS verwendet LLVM/dev/urandom als Quelle, die laut [this] (https://www.apple.com/br/ipad/business/docs/iOS_Security_Oct12.pdf) garantiert kryptographisch sicher ist) (Seite 7). Auf Android verwendet gcc entweder/dev/random oder/dev/urandom als Quelle, daher kann ich mich dafür entscheiden, mit "/ dev/random" zu initialisieren, was von OpenSSl und anderen verwendet wird und garantiert (nach bestem Wissen von Android) dass es nicht deterministisch ist –

+2

Wenn Sie a priori 'random_device's Quellen kennen, die für die Verwendung als CSPRNG geeignet sind, dann ist das natürlich eine geeignete Wahl. Aber ich wäre immer noch vorsichtig mit Ihrer 'mt19937' Idee. Eine einfache Regel, wenn es um Kryptographie geht, sollte, wenn Sie nicht ein Experte in diesem Bereich sind, immer eine bestehende bewährte Lösung gegenüber etwas scheinbar cleverem bevorzugen. Es ist viel wahrscheinlicher, dass du etwas vermasselst als mit einer wirklich neuen Idee. Haben Sie den Durchsatz Ihrer Idee getestet? 'mt19937' hat 19937 Bits des Zustands, daher kann häufiges erneutes Auslesen nicht viel besser als' random_device' sein – Praetorian

Antwort

6

Tun Sie dies nicht. Ernsthaft, tu es einfach nicht. Dies bedeutet nicht nur Ärger - es ist eher so, als ob man um Ärger bittet und bettelt, indem man in den am meisten kriminellen Teil der gefährlichsten Stadt geht, die man finden kann und die viele Wertsachen trägt.

Anstatt zu versuchen, MT 19937 oft genug zu regenerieren, um zu vertuschen, wie unsicher es ist, rate ich Ihnen, Ihre Zufallszahlen zu generieren, indem Sie AES im Counter-Modus ausführen. Dies erfordert, dass Sie eine (aber nur eine) gute Zufallszahl mit der richtigen Größe erhalten, die Sie als Ausgangsmaterial für Ihren Generator verwenden können.

Sie verwenden dies als Schlüssel für AES und verwenden es einfach zum Verschlüsseln sequenzieller Zahlen, um einen zufälligen Ausgabestrom zu erhalten, der jedoch leicht zu reproduzieren ist.

Dies hat viele Vorteile. Erstens verwendet es einen Algorithmus, der tatsächlich intensiv studiert wurde und allgemein als sicher gilt. Zweitens bedeutet dies, dass Sie nur eine (ziemlich kleine) Zufallszahl als "Schlüssel" für das System als Ganzes verteilen müssen. Drittens gibt es wahrscheinlich besseren Durchsatz. Sowohl Intel's als auch (scheinbar) independent tests zeigen einen Durchsatzbereich, der mit dem anfängt, was Sie für MT 19937 am unteren Ende und bis zu 4-5 mal schneller am oberen Ende des Kurses fordern. Angesichts der Art und Weise, wie Sie es verwenden, würde ich erwarten, dass Sie Ergebnisse in der Nähe des oberen Endes des Bereichs, den sie zeigen, erhalten (und möglicherweise sogar übertreffen).

Fazit: AES im Counter-Modus ist offensichtlich eine bessere Lösung für das vorliegende Problem. Das Beste, auf das Sie hoffen können, ist, dass MT 19937 fast genauso schnell und nahezu sicher ist. In Wirklichkeit wird es wahrscheinlich beide Hoffnungen enttäuschen und sowohl langsamer als auch wesentlich unsicherer werden.


1. Wie wäre es, diese Ergebnisse übertreffen? Diese basieren zweifellos auf der Verschlüsselung von Massendaten - d. H. Lesen eines Datenblocks aus dem RAM, Verschlüsseln und Schreiben des Ergebnisses in den RAM. In Ihrem Fall müssen Sie das Ergebnis nicht aus dem RAM lesen - Sie müssen nur fortlaufende Zahlen in der CPU generieren, sie verschlüsseln und die Ergebnisse ausgeben.

5

Die kurze Antwort ist, nein, Sie können nicht. Die Anforderungen an einen kryptografisch sicheren RNG sind sehr hoch und wenn Sie diese Frage hier stellen müssen, sind Sie sich dieser Anforderungen nicht ausreichend bewusst.Wie Jerry sagt, AES-CTR ist eine Option, wenn Sie Wiederholbarkeit benötigen. Eine andere Option, die keine Wiederholbarkeit zulässt, wäre die Suche nach einer Implementierung von Yarrow oder Fortuna für Ihr System. Im Allgemeinen ist es viel besser, eine CSRNG in einer Bibliothek zu finden, als selbst zu rollen. Bibliotheksverfasser sind ausreichend über die Anforderungen für eine gute CSRNG informiert.