it-swarm.com.de

Zufallszahlen in Javascript sichern?

Wie erstelle ich kryptografisch sichere Zufallszahlen in Javascript?

75
Kyle

Sie können zum Beispiel die Mausbewegung als Ausgangswert für Zufallszahlen verwenden, die Zeit und die Mausposition immer dann auslesen, wenn das Ereignis onmousemove eintritt, diese Daten einer Whitening-Funktion zuführen und Sie haben einige erstklassige Zufallszahlen zur Hand. Stellen Sie jedoch sicher, dass der Benutzer die Maus ausreichend bewegt hat, bevor Sie die Daten verwenden.

Edit: Ich habe selbst ein bisschen mit dem Konzept gespielt, indem ich einen Passwortgenerator erstellt habe. Ich würde nicht garantieren, dass meine Bleaching-Funktion fehlerfrei ist, aber da ich ständig nachgeprüft werde, bin ich mir ziemlich sicher, dass es für den Job ausreichend ist: ebusiness.hopto.org /generator.htm

Edit2: Es funktioniert jetzt irgendwie mit Smartphones, aber nur durch Deaktivieren der Touch-Funktionalität, während die Entropie gesammelt wird. Android funktioniert anders nicht richtig.

23
aaaaaaaaaaaa

Bei WHATWG wurde darüber diskutiert, dies dem window.crypto-Objekt hinzuzufügen. Sie können die Diskussion lesen und das vorgeschlagene API und den Webkit-Fehler (22049) nachlesen.

Testen Sie einfach den folgenden Code in Chrome , um ein zufälliges Byte zu erhalten:

(function(){
  var buf = new Uint8Array(1);
  window.crypto.getRandomValues(buf);
  alert(buf[0]);
})();
58
Paul V

In Ordnung, ich denke, Ihre besten Wetten sind:

  1. window.crypto.getRandomValues ​​oder window.msCrypto.getRandomValues
  2. Die randomWords-Funktion der sjcl-Bibliothek ( http://crypto.stanford.edu/sjcl/ )
  3. Der Zufallszahlengenerator der isaac-Bibliothek (der von Math.random festgelegt wurde und daher nicht wirklich kryptografisch sicher ist) ( https://github.com/rubycon/isaac.js )

window.crypto.getRandomValues ​​ist seit einiger Zeit in Chrome) implementiert und seit relativ kurzer Zeit auch in Firefox. Leider implementieren Internet Explorer 10 und frühere Versionen die Funktion nicht. IE 11 hat window.msCrypto, was dasselbe bewirkt. Sjcl hat einen großartigen Zufallszahlengenerator, der durch Mausbewegungen erzeugt wurde, aber es besteht immer die Möglichkeit, dass sich entweder die Maus nicht ausreichend bewegt hat, um den Generator zu erzeugen, oder Da sich der Benutzer auf einem mobilen Gerät befindet, auf dem keine Mausbewegung stattfindet, empfehle ich einen Fallback-Fall, in dem Sie auch dann eine nicht sichere Zufallszahl erhalten können, wenn Sie keine andere Wahl haben.

function GetRandomWords (wordCount) {
    var randomWords;

    // First we're going to try to use a built-in CSPRNG
    if (window.crypto && window.crypto.getRandomValues) {
        randomWords = new Int32Array(wordCount);
        window.crypto.getRandomValues(randomWords);
    }
    // Because of course IE calls it msCrypto instead of being standard
    else if (window.msCrypto && window.msCrypto.getRandomValues) {
        randomWords = new Int32Array(wordCount);
        window.msCrypto.getRandomValues(randomWords);
    }
    // So, no built-in functionality - bummer. If the user has wiggled the mouse enough,
    // sjcl might help us out here
    else if (sjcl.random.isReady()) {
        randomWords = sjcl.random.randomWords(wordCount);
    }
    // Last resort - we'll use isaac.js to get a random number. It's seeded from Math.random(),
    // so this isn't ideal, but it'll still greatly increase the space of guesses a hacker would
    // have to make to crack the password.
    else {
        randomWords = [];
        for (var i = 0; i < wordCount; i++) {
            randomWords.Push(isaac.Rand());
        }
    }

    return randomWords;
};

Sie müssen sjcl.js und isaac.js für diese Implementierung einschließen und den sjcl-Entropiekollektor starten, sobald Ihre Seite geladen ist:

sjcl.random.startCollectors();

sjcl ist BSD und GPL mit doppelter Lizenz, während isaac.js MIT ist. Es ist also absolut sicher, beide in jedem Projekt zu verwenden. Wie in einer anderen Antwort erwähnt, ist Clipperz eine weitere Option. Aus irgendeinem bizarren Grund wird es jedoch unter der AGPL lizenziert. Ich habe noch niemanden gesehen, der zu verstehen scheint, welche Auswirkungen dies auf eine JavaScript-Bibliothek hat, aber ich würde es generell vermeiden.

Eine Möglichkeit, den von mir veröffentlichten Code zu verbessern, besteht darin, den Status des isaac-Zufallszahlengenerators in localStorage zu speichern, damit er nicht bei jedem Laden der Seite neu sortiert wird. Isaac generiert eine zufällige Sequenz, aber für Kryptografiezwecke ist der Keim entscheidend. Das Seeding mit Math.random ist schlecht, aber zumindest ein bisschen weniger schlecht, wenn es nicht unbedingt bei jedem Seitenaufruf erfolgt.

27
ZeroG

Verwenden Sie window.crypto.getRandomValues , wie folgt:

var random_num = new Uint8Array(2048 / 8); // 2048 = number length in bits
window.crypto.getRandomValues(random_num);

Dies ist wird in allen modernen Browsern unterstützt und verwendet den Zufallsgenerator des Betriebssystems (z. B. /dev/urandom ). Wenn Sie eine IE11-Kompatibilität benötigen, müssen Sie deren Implementierung mit dem Präfix viavar crypto = window.crypto || window.msCrypto; crypto.getRandomValues(..) verwenden.

Beachten Sie, dass die API window.crypto Auch generiere Schlüssel direkt kann, was die bessere Option sein kann.

11
phihag

Vielleicht möchten Sie es mit http://sourceforge.net/projects/clipperzlib/ versuchen. Dabei handelt es sich um eine Implementierung von Fortuna , einem kryptografisch sicheren Zufallszahlengenerator. (Schauen Sie sich src/js/Clipperz/Crypto/PRNG.js an.) Es scheint, als würde die Maus auch als Zufallsquelle dienen.

4
ameer

um eine kryptografisch starke Zahl aus dem Bereich [0, 1) zu erhalten (ähnlich wie bei Math.random()), verwenden Sie crypto :

let random = ()=> crypto.getRandomValues(new Uint32Array(1))[0]/2**32;

console.log( random() );
4

Zunächst benötigen Sie eine Entropiequelle. Zum Beispiel die Bewegung der Maus, des Passworts oder eines anderen. Alle diese Quellen sind jedoch weit vom Zufall entfernt und garantieren Ihnen 20 Bit Entropie, selten mehr. Der nächste Schritt, den Sie ausführen müssen, ist die Verwendung des Mechanismus wie "Passwort-basiertes KDF", der die rechnerische Unterscheidung von zufälligen Daten erschwert.

1
user2674414