it-swarm.com.de

Wie kann ich eine Zufallszahl erstellen, die in Python kryptografisch sicher ist?

Ich mache ein Projekt in Python und möchte eine Zufallszahl erstellen, die kryptographisch sicher ist. Wie kann ich das tun? Ich habe online gelesen, dass die vom regulären Randomizer generierten Zahlen nicht kryptographisch sicher sind und dass die Funktion os.urandom(n) mir einen String und keine Zahl zurückgibt. 

56
user2835118

Sie können eine Liste von Zufallszahlen erhalten, indem Sie einfach die Funktion ord auf die von os.urandom zurückgegebenen Bytes anwenden

>>> import os
>>> os.urandom(10)
'm\xd4\x94\x00x7\xbe\x04\xa2R'
>>> type(os.urandom(10))
<type 'str'>
>>> map(ord, os.urandom(10))
[65, 120, 218, 135, 66, 134, 141, 140, 178, 25]

Zitieren os.urandom Dokumentation,

Gibt eine Zeichenfolge aus n zufälligen Bytes zurück, die für den kryptographischen Gebrauch geeignet sind.

Diese Funktion gibt zufällige Bytes von einer betriebssystemspezifischen Zufallsquelle zurück. Die zurückgegebenen Daten sollten für kryptografische Anwendungen unvorhersehbar sein, ihre genaue Qualität hängt jedoch von der Betriebssystemimplementierung ab. Auf einem UNIX-ähnlichen System wird /dev/urandom abgefragt, und unter Windows wird CryptGenRandom() verwendet.

39
thefourtheye

Da Sie Ganzzahlen in einem bestimmten Bereich generieren möchten, ist es viel einfacher, stattdessen die Klasse random.SystemRandom zu verwenden. Wenn Sie eine Instanz dieser Klasse erstellen, erhalten Sie ein Objekt, das alle Methoden des random-Moduls unterstützt, jedoch os.urandom() unter den Abdeckungen verwendet. Beispiele:

>>> from random import SystemRandom
>>> cryptogen = SystemRandom()
>>> [cryptogen.randrange(3) for i in range(20)] # random ints in range(3)
[2, 2, 2, 2, 1, 2, 1, 2, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0]
>>> [cryptogen.random() for i in range(3)]  # random floats in [0., 1.)
[0.2710009745425236, 0.016722063038868695, 0.8207742461236148]

Wenn Sie urandom() direkt verwenden, müssen Sie eigene Algorithmen entwickeln, um die zufälligen Bytes in die gewünschten Ergebnisse umzuwandeln. Mach das nicht ;-) SystemRandom erledigt es für dich.

Beachten Sie diesen Teil der Dokumente:

klasse random.SystemRandom ([Seed]) 

Klasse, die die Funktion os.urandom () zum Generieren von Zufallszahlen aus vom Betriebssystem bereitgestellten Quellen verwendet. Nicht auf allen Systemen verfügbar. Verlässt sich nicht auf den Software-Status und Sequenzen sind nicht reproduzierbar. Dementsprechend haben die seed () - und die jumpahead () -Methode keine Auswirkungen und werden ignoriert. Die Methoden getstate () und setstate () lösen NotImplementedError aus, wenn sie aufgerufen werden.

59
Tim Peters

Python 3.6 führt ein neues secret-Modul ein , das "Zugriff auf die sicherste Zufallsquelle bietet, die Ihr Betriebssystem bietet" Um einige kryptographisch sichere Nummern zu generieren, können Sie secrets.randbelow() anrufen.

secrets.randbelow(n)

was eine Zahl zwischen 0 und n zurückgibt.

23
Cody Piersall

Wenn Sie eine n-Bit-Zufallszahl wünschen, ist die unter Python 2.4+ einfachste Methode die ich gefunden habe

import random
random.SystemRandom().getrandbits(n)

Beachten Sie, dass SystemRandomos.urandom() verwendet, daher ist das Ergebnis dieser Methode nur so gut wie die urandom()-Implementierung Ihres Systems.

6
jjlin

Um eine kryptografisch sichere pseudozufällige Ganzzahl zu generieren, können Sie folgenden Code verwenden:

int(binascii.hexlify(os.urandom(n)),16)

Wo n eine ganze Zahl ist und je größer n ist, desto größer ist die generierte ganze Zahl.

Sie müssen zuerst os und binascii importieren.

Das Ergebnis dieses Codes kann je nach Plattform variieren.

0