web-dev-qa-db-ja.com

Pythonで暗号的に安全な乱数を作成するにはどうすればよいですか?

pythonでプロジェクトを作成しています。暗号的に安全な乱数を作成したいのですが、どうすればよいですか?通常のランダマイザーによって生成された数値は暗号的に安全ではなく、関数os.urandom(n)は数字ではなく文字列を返します。

60
user2835118

このように ord 関数を _os.urandom_ によって返されるバイトに適用するだけで、乱数のリストを取得できます。

_>>> 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]
_

_os.urandom_ドキュメントを引用して、

暗号化用途に適したnランダムバイトの文字列を返します

この関数は、OS固有の乱数ソースからランダムバイトを返します。正確な品質はOSの実装に依存しますが、返されるデータは暗号化アプリケーションに十分なほど予測不能でなければなりません。 UNIXのようなシステムでは、これは_/dev/urandom_を照会し、WindowsではCryptGenRandom()を使用します。

39
thefourtheye

特定の範囲の整数を生成するため、代わりに_random.SystemRandom_クラスを使用する方がはるかに簡単です。そのクラスのインスタンスを作成すると、randomモジュールのすべてのメソッドをサポートするオブジェクトが提供されますが、os.urandom()を使用します。例:

_>>> 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]
_

などurandom()を直接使用して、生成するランダムバイトを希望する結果に変換する独自のアルゴリズムを考案する必要があります。それをしないでください;-) SystemRandomはあなたのためにそれをします。

ドキュメントのこの部分に注意してください。

クラスrandom.SystemRandom([seed])

オペレーティングシステムが提供するソースから乱数を生成するためにos.urandom()関数を使用するクラス。すべてのシステムで利用できるわけではありません。ソフトウェアの状態に依存せず、シーケンスは再現できません。したがって、seed()およびjumpahead()メソッドは効果がなく、無視されます。 getstate()およびsetstate()メソッドは、呼び出されるとNotImplementedErrorを発生させます。

62
Tim Peters

Python 3.6は、新しい secretsモジュール を導入します。これは、「オペレーティングシステムが提供する最も安全なランダム性のソースへのアクセスを提供します。 」暗号的に安全な番号を生成するために、 secrets.randbelow() を呼び出すことができます。

secrets.randbelow(n)

0からnの間の数値を返します。

25
Cody Piersall

n- bit乱数が必要な場合、Python 2.4+の下で、私が見つけた最も簡単な方法は

_import random
random.SystemRandom().getrandbits(n)
_

SystemRandomos.urandom()を使用するため、このメソッドの結果は、システムのurandom()実装と同じくらい良いことに注意してください。

6
jjlin

暗号的に安全な擬似乱数整数を生成するには、次のコードを使用できます。

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

ここで、nは整数であり、nが大きいほど、生成される整数は大きくなります。

最初にosbinasciiをインポートする必要があります。

このコードの結果は、プラットフォームによって異なる場合があります。

1