Frage

Wenn Sie eine kryptographisch starke Zufallszahl in Java möchten, verwenden Sie SecureRandom. Leider kann SecureRandom sehr langsam sein. Wenn es /dev/random auf Linux verwendet, kann es Warte Block für eine ausreichende Entropie bis zu bauen. Wie beurteilen Sie die Performance-Einbußen vermeiden?

Hat jemand verwendet Gelegentlich Mathematik als eine Lösung für dieses Problem ?

Kann jemand bestätigen, dass dieses Leistungsproblem wird in JDK 6?

gelöst
War es hilfreich?

Lösung

Wenn Sie echte Zufallsdaten wollen, dann leider müssen Sie warten, bis es. Dazu gehört auch die Samen für eine SecureRandom PRNG. Gelegentlich Mathematik kann nicht sammeln echte Zufallsdaten schneller als SecureRandom, obwohl es mit dem Internet verbinden kann Seed-Daten von einer bestimmten Website zum Download bereit. Meine Vermutung ist, dass dies unwahrscheinlich ist /dev/random schneller zu sein als dort, wo das ist, zur Verfügung.

Wenn Sie eine PRNG wollen, tun Sie etwas wie folgt aus:

SecureRandom.getInstance("SHA1PRNG");

Welche Zeichenketten sind, hängt von der SecureRandom SPI-Anbieter unterstützt, aber Sie können sie Security.getProviders() und Provider.getService() mit aufzuzählen.

Sun liebt SHA1PRNG, so dass es weit verbreitet ist. Es ist nicht besonders schnell wie PRNGs gehen, aber PRNGs wird nur Zahlen werden Knirschen, nicht für physikalische Messung der Entropie zu blockieren.

Die Ausnahme ist, wenn Sie Daten nicht setSeed() rufen, bevor man dann die PRNG selbst einmal das erste Mal, wenn Sie next() oder nextBytes() nennen Saatgut wird. Es wird dies in der Regel tun, um eine ziemlich kleine Menge von echten Zufallsdaten aus dem System. Dieser Aufruf kann blocken, aber Ihre Quelle für Zufallszahlen weitaus sicherer als jede Variante von „hash die aktuelle Uhrzeit zusammen mit der PID, fügen Sie 27, und hoffen das Beste“ machen. Wenn alles was Sie brauchen Zufallszahlen für ein Spiel ist, obwohl, oder wenn Sie den Strom wollen für Testzwecke die gleiche Saatgut sein wiederholbare in Zukunft verwendet wird, ein unsicherer Samen ist immer noch nützlich.

Andere Tipps

Es sollte möglich sein, den wählen schneller-but-leicht-weniger-secure / dev / urandom unter Linux mit:

-Djava.security.egd=file:/dev/urandom

Allerdings bedeutet dies nicht mit Java arbeiten 5 und höher ( Java Bug 6202721 ). Die vorgeschlagene Workaround zu bedienen ist:

-Djava.security.egd=file:/dev/./urandom

(beachten Sie die zusätzliche /./)

Unter Linux die Standardimplementierung für SecureRandom ist NativePRNG (Quellcode hier ), die sehr langsam sein tendiert. Unter Windows ist die Standard SHA1PRNG, die wie andere darauf hingewiesen, auch auf Linux verwenden können, wenn Sie es explizit angeben.

NativePRNG unterscheidet sich von SHA1PRNG und Uncommons Mathe AESCounterRNG in denen sie empfängt kontinuierlich die Entropie von dem Betriebssystem (durch von /dev/urandom Lesen). Die anderen PRNGs erwerben keine zusätzliche Entropie nach der Aussaat.

AESCounterRNG ist etwa 10x schneller als SHA1PRNG, die IIRC selbst zwei- bis dreimal schneller als NativePRNG.

Wenn Sie eine schnellere PRNG benötigen, die Entropie nach der Initialisierung erfasst, ob Sie eine Java-Implementierung von Fortuna . Der Kern PRNG eine Fortuna-Implementierung ist identisch mit dem von AESCounterRNG verwendet, aber es ist auch ein ausgeklügeltes System von Entropie-Pooling und automatischen Nachsaat.

Viele Linux-Distributionen (meist Debian-basiert) OpenJDK konfigurieren /dev/random für Entropie zu verwenden.

/dev/random ist definitionsgemäß langsam (und kann sogar Block).

Von hier aus haben Sie zwei Möglichkeiten, wie man es entsperren:

  1. Verbessern Entropie oder
  2. Reduzieren Zufälligkeit Anforderungen.

Option 1, Improve Entropie

Um mehr Entropie in /dev/random zu bekommen, versuchen Sie die haveged Daemon. Es ist ein Dämon, der kontinuierlich HAVEGE Entropie sammelt, und arbeitet auch in einer virtualisierten Umgebung, weil es keine spezielle Hardware benötigt, nur die CPU selbst und eine Uhr.

Unter Ubuntu / Debian:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

Auf RHEL / CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

Option 2. Reduzieren Zufälligkeit Anforderungen

Wenn aus irgendeinem Grund über die Lösung nicht hilft oder Sie kümmern sich nicht um kryptographisch starke Zufalls, Sie können wechseln, anstatt /dev/urandom, die garantiert nicht zu blockieren.

es global zu tun, bearbeiten Sie die Datei jre/lib/security/java.security in Ihrem Standard-Java-Installation /dev/urandom zu verwenden (durch eine andere Bug es muss als /dev/./urandom angegeben werden).

Wie folgt aus:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

Dann werden Sie nicht immer es auf der Kommandozeile angeben müssen.


Hinweis: Wenn Sie Kryptographie tun, Sie Notwendigkeit gute Entropie. Case in point -. android PRNG Ausgabe die Sicherheit der Bitcoin Portemonnaies reduziert

Ich hatte ein ähnliches Problem mit Anrufen für etwa 25 Sekunden auf einmal auf einem kopflos Debian-Server SecureRandom blockiert. Ich installierte die haveged Daemon /dev/random, um sicherzustellen, gehalten wird aufgestockt, auf Headless-Server Sie so etwas wie dieses benötigen die erforderliche Entropie zu erzeugen. Meine Anrufe jetzt vielleicht nehmen Millisekunden SecureRandom.

Wenn Sie wirklich „kryptographisch stark“ Zufälligkeit wollen, dann müssen Sie eine starke Entropiequelle. /dev/random ist langsam, da es für Systemereignisse warten muss, sammeln Entropie (Disk liest, Netzwerkpakete, Mausbewegung, Tastendrücke, usw.).

Eine schnellere Lösung ist ein Hardware-Zufallszahlengenerator. Sie können bereits ein auf die Hauptplatine eingebaut; Besuche die hw_random Dokumentation Anweisungen zum herauszufinden, wenn Sie es haben, und wie es zu benutzen. Das RNG-Tools-Paket enthält einen Daemon, die Hardware erzeugte Entropie in /dev/random füttern wird.

Wenn ein HRNG auf Ihrem System nicht verfügbar ist, und Sie sind bereit, Entropie Kraft für die Leistung zu opfern, werden Sie eine gute PRNG mit Daten aus /dev/random auf Saatgut, und lassen Sie die PRNG den Großteil der Arbeit tun. Es gibt mehrere PRNG die in SP800-90 , die einfach zu implementieren ist.

Es gibt ein Tool (auf Ubuntu zumindest) ist die künstliche Zufälligkeit in Ihr System einfließen werden. Der Befehl ist einfach:

rngd -r /dev/urandom

und Sie können an der Front ein sudo müssen. Wenn Sie nicht rng-tools-Paket haben, müssen Sie es installieren. Ich habe versucht, diese, und es hat mir geholfen, auf jeden Fall!

Quelle: matt vs Welt

ich konfrontierte gleiche Ausgabe . Nachdem einige mit den richtigen Suchbegriffen googeln, stieß ich auf diesem schönen Artikel auf DigitalOcean .

haveged ist eine mögliche Lösung auf Sicherheit ohne Kompromisse.

Ich zitiere nur den relevanten Teil aus dem Artikel hier.

  

auf dem HAVEGE Prinzip Basierend und zuvor auf der Grundlage ihres zugehörigen   Bibliothek, ermöglicht haveged Erzeugung Zufälligkeit auf Basis von Änderungen in   Code Ausführungszeit auf einem Prozessor. Da ist es fast unmöglich,   ein Stück Code genau die gleiche Zeit in Anspruch nehmen, auch in der zur Ausführung   gleiche Umgebung auf derselben Hardware, die zeitliche Steuerung ein einzigen Lauf   oder mehrere Programme sollten geeignet sein, eine zufällige Quelle auf Saatgut. Das   haveged Implementierung Samen Zufallsquelle Ihres Systems (in der Regel   / Dev / random) unter Verwendung von Differenzen in Zeitstempelzähler Ihr Prozessor   (TSC), nachdem eine Schleife wiederholtes Ausführen

Wie installiert man haveged

Führen Sie die Schritte in diesem Artikel. https: // www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

Ich habe gepostet es hier

Mit dem sicheren Zufall als Initialisierung Quelle für einen wiederkehrenden Algorithmus; Sie könnten eine Mersenne-Twister für den Großteil der Arbeit statt des einen in UncommonMath, die für eine Weile gewesen verwenden dann um und bewährte besser als andere PRNG

http://en.wikipedia.org/wiki/Mersenne_twister

Vergewissern Sie sich von Zeit zu Zeit die sicheren Zufalls verwendet für die Initialisierung aktualisieren, zum Beispiel Sie eine sichere zufällig generierte pro Kunde haben könnte, eine Mersenne-Twister-Pseudo-Zufallsgenerator pro Client, einen ausreichend hohen Grad der Randomisierung zu erhalten

Mit Java 8, fand ich, dass unter Linux Aufruf SecureRandom.getInstanceStrong() mir den NativePRNGBlocking Algorithmus würde. Dies würde oft blockieren für viele Sekunden ein paar Bytes von Salz zu erzeugen.

Ich schaltete explizit für NativePRNGNonBlocking zu fragen, statt, und wie aus dem Namen zu erwarten, es nicht mehr blockiert. Ich habe keine Ahnung, was die Auswirkungen auf die Sicherheit dafür sind. Vermutlich ist die nicht-blockierende Version die Menge der Entropie nicht garantieren kann, verwendet wird.

Aktualisieren : Ok, ich diese ausgezeichnete Erklärung .

Auf den Punkt gebracht, um zu verhindern Verwendung new SecureRandom() Blockierung. Dies verwendet /dev/urandom, die nicht blockiert und ist im Grunde so sicher wie /dev/random. Vom Post. „Die einzige Zeit, die Sie anrufen wollen / dev / random ist, wenn die Maschine zuerst das Booten ist, und Entropie noch nicht angesammelt hat“

SecureRandom.getInstanceStrong() gibt Ihnen die absolute stärkste RNG, aber es ist nur sicher, in Situationen zu verwenden, in denen eine Reihe von Sperr werden Sie nicht bewirken.

Das Problem, das Sie über /dev/random verwiesen wird, ist nicht mit dem SecureRandom Algorithmus, aber mit der Quelle der Zufälligkeit, die es verwendet. Die beiden sind orthogonal. Sie sollten herausfinden, welche der beiden Sie verlangsamt.

Gelegentlich Maths Seite, die Sie explizit erwähnt verbunden, dass sie nicht die Quelle der Zufälligkeit Adressierung.

Sie können verschiedenen JCE-Anbieter versuchen, wie BouncyCastle, um zu sehen, ob ihre Umsetzung SecureRandom schneller ist.

Ein kurzer sucht zeigt auch Linux-Patches, die den Standard ersetzen Umsetzung mit Fortuna. Ich weiß nicht viel darüber, aber Sie sind willkommen zu untersuchen.

Ich soll auch erwähnen, dass, obwohl es sehr gefährlich ist, einen schlecht umgesetzt SecureRandom Algorithmus und / oder Zufälligkeit Quelle zu verwenden, können Sie Ihren eigenen JCE Provider mit einer benutzerdefinierten Implementierung von SecureRandomSpi rollen können. Sie müssen durch einen Prozess mit Sun gehen, den Anbieter zu bekommen unterzeichnet, aber es ist eigentlich ziemlich einfach; sie müssen nur Sie sie ein Formular faxen besagt, dass Sie der US-Exportbeschränkungen für Krypto-Bibliotheken bewusst sind.

ich nicht gegen dieses Problem getroffen habe mich, aber ich würde einen Thread beim Programmstart laichen, die sofort versucht, einen Samen zu erzeugen, dann stirbt. Die Methode, die Sie für randoms rufen zu diesem Thread beitreten wird, wenn er am Leben ist so der erste Anruf blockiert nur, wenn es sehr früh in der Programmausführung auftritt.

Meine Erfahrung hat mit langsamer Initialisierung des PRNG nur gewesen, nicht mit der Erzeugung von Zufallsdaten danach. Versuchen Sie, eine eifrige Initialisierung Strategie. Da sie zu schaffen sind teuer, behandeln sie einen Singleton mögen und die gleiche Instanz wiederverwenden. Wenn es für eine Instanz zu viel Thread-Konkurrenz ist, bündeln sie oder sie Thread-local machen.

Machen Sie keine Kompromisse auf Erzeugung von Zufallszahlen. Eine Schwäche dort Kompromisse all Ihre Sicherheit.

Ich sehe eine Menge von COTS Atomzerfall-basierten Generatoren, aber es gibt nicht mehr Pläne gibt für sie, wenn Sie wirklich eine Menge von Zufallsdaten benötigen. Eine Website, die immer wieder interessante Dinge hat, zu betrachten, einschließlich HotBits, ist John Walker Fourmilab.

Es klingt wie Sie klarer über Ihre RNG Anforderungen sein sollte. Die stärkste Verschlüsselungs RNG Anforderung (wie ich es verstehe) wäre, dass selbst wenn Sie der Algorithmus kennen verwendet, um sie zu erzeugen, und Sie wissen alle zuvor erzeugten Zufallszahlen, könnten Sie keine nützlichen Informationen über jede der Zufallszahlen in die erzeugte erhalten Zukunft, ohne dafür eine unpraktische Menge an Rechenleistung.

Wenn Sie nicht über diese volle Garantie der Zufälligkeit müssen dann gibt es wahrscheinlich entsprechende Leistung Kompromisse. Ich würde dazu neigen, mit Dan Dyer Antwort zustimmen über AESCounterRNG von Uncommons-Mathe oder Fortuna (einer seiner Urheber ist Bruce Schneier, ein Experte in der Kryptographie). Ich habe auch nie aber die Ideen erscheinen seriös auf den ersten Blick.

Ich würde denkt , wenn Sie könnten einen anfänglichen Zufallskeim periodisch erzeugen (zB einmal pro Tag oder Stunde oder was auch immer), Sie einen schnellen Stromchiffre verwenden könnten Zufallszahl von aufeinander folgenden Segmenten der erzeugen Strom (wenn die Stromchiffre XOR verwendet dann in einem Strom von Nullen nur passieren oder die XOR-Bits direkt greifen). ECRYPT eStream Projekt hat viele gute Informationen, einschließlich Performance-Benchmarks. Dies würde nicht Entropie zwischen den Zeitpunkten halten, dass Sie es wieder aufzufüllen, so dass, wenn jemand eine der Zufallszahlen kannte und der Algorithmus, den Sie verwendeten, technisch könnte es möglich sein, mit viel Rechenleistung, die Stromchiffre zu brechen und erraten seinen internen Zustand in der Lage sein Zukunft Zufallszahlen vorherzusagen. Aber Sie würden sich entscheiden müssen, ob das Risiko und seine Folgen ausreichen, um die Kosten für die Aufrechterhaltung Entropie zu rechtfertigen.

Edit: hier einige Verschlüsselungs natürlich Hinweise auf RNG fand ich auf dem ‚Netz, die zu diesem Thema sehr relevant betrachten.

Wenn Ihre Hardware unterstützt es versuchen mit Java RdRand Dienstprogramm von denen ich der Autor bin .

Sein basierte auf Intels RDRAND Instruktion und ist etwa 10-mal schneller als SecureRandom und keine Probleme mit der Bandbreite für großvolumige Umsetzung.


Beachten Sie, dass diese Implementierung nur auf der CPU arbeitet, die den Befehl zur Verfügung stellen (das heißt, wenn der rdrand Prozessor-Flag gesetzt ist). Sie müssen explizit durch den RdRandRandom() Konstruktor instanziiert; keine spezifische Provider wurde implementiert.

Etwas anderes zu betrachten ist die Eigenschaft securerandom.source in der Datei lib / security / java.security

Es kann ein Leistungsvorteil sein mit / dev / urandom anstatt / dev / random. Denken Sie daran, dass, wenn die Qualität der Zufallszahlen wichtig ist, keinen Kompromiss machen, die Sicherheit bricht.

Sie können Apache commons Math Projekt versuchen, die einige Implementierungen von gut bekannten Algorithmen hat:

https://commons.apache.org/proper/commons- math / -Nutzerhandbuch / random.html

Seien Sie jedoch vorsichtig mit der Leistung. Der Standardkonstruktor von RandomDataGenerator erstellt eine dedizierte Instanz von Well19937c, dass eine sehr teure Operation ist.

Nach der Dokumentation dieser Klasse nicht Thread-sicher, aber wenn Sie garantieren können, dass nur ein Thread diese Klasse zugreifen, können Sie nur eine Instanz pro Thema initialisieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top