2014-01-05 53 views
45

我正在做一個python項目,我想創建一個密碼安全的隨機數,我該怎麼做?我已經在網上閱讀過,由常規隨機數發生器生成的數字不是加密安全的,並且函數os.urandom(n)給我返回一個字符串,而不是一個數字。如何創建一個在python中以密碼方式安全的隨機數字?

+0

您得到的答案是正確的開始,但您需要準確定義「數字」的含義。浮動?一個整數?簽名或未簽名?什麼範圍?等。 –

+0

我已經得到了我的口水,但我的intenton是和整數(應該提到)。有什麼辦法可以設定一個特定的範圍來解釋這個製造者的建議嗎? – user2835118

+0

@TimPeters你可以請檢查我的更新答案是否可以嗎? – thefourtheye

回答

31

您可以只把它運用在由os.urandom返回的字節ord功能,這樣

>>> 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特定的隨機源中返回隨機字節。返回的數據對於加密應用程序來說應該是不可預知的,儘管它的確切質量取決於操作系統的實現。在類UNIX系統上,這將查詢/dev/urandom,在Windows上它將使用CryptGenRandom()

+1

對於那些想知道是否urandom真正適合加密使用,[顯然它是](http://security.stackexchange.com/questions/3936/is-a-rand-from-dev-urandom-secure-for-a-login-key)。 – Claudiu

47

由於您想在某個特定範圍內生成整數,所以使用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([種子])

類使用該os.urandom()函數用於從由所述操作提供源產生隨機數系統。不適用於所有系統。不依賴軟件狀態,序列不可重現。因此,seed()和jumpahead()方法不起作用並被忽略。如果調用getstate()和setstate()方法會引發NotImplementedError。

+0

這也是一個非常好的答案,我覺得不好實現它(會一直襬弄,直到我得到一個範圍,我想與其他答案)。你確定它是密碼安全的嗎? – user2835118

+1

@ user2835118,它與您的操作系統對'os.urandom'的實現完全一樣安全 - 或不安全。這意味着「和編寫操作系統的人一樣安全,知道如何做到這一點」。在生活中沒有絕對的保證;-)但是對於所有的實際目的而言,是的,如果它不是基於當前所有知識的密碼安全性,那將是驚人的。 –

+2

@ user2835118你可能想要通過這個答案一次http://security.stackexchange.com/a/3939/24680 – thefourtheye

5

如果你想要一個n位的隨機數,Python的2.4 +下,我發現最簡單的方法是

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

注意SystemRandom使用os.urandom(),所以這種方法的結果是隻和你係統的實現一樣好。

11

Python 3.6引入了一個新的secrets module,它提供了訪問操作系統提供的最安全的隨機性來源。爲了生成一些加密安全號碼,您可以撥打secrets.randbelow()

secrets.randbelow(n) 

這將返回一個介於0和n之間的數字。

0

要生成密碼安全僞隨機整數,你可以使用下面的代碼:

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

哪裏n是生成一個整數,並n越大,越大的整數。

您必須首先輸入osbinascii

此代碼的結果可能因平臺而異。

相關問題