如何使用隨機(jī)數(shù)生成器來生成私鑰
比特幣用戶很喜歡討論“非對稱加密”、“橢圓曲線”、“量子計(jì)算機(jī)”這類高深莫測的話題,然后再以一種非常莫名其妙的方式把幣弄丟,比如說:“隨機(jī)”。
之前曾爆出的 brainwallet.org 網(wǎng)站用戶丟幣事件,就是因?yàn)殡S機(jī)函數(shù)的問題。
隨機(jī)很重要,對于比特幣這種密碼學(xué)電子貨幣來說,尤其重要。
說到隨機(jī),有兩個(gè)必須要搞清楚的概念:“真隨機(jī)數(shù)生成器”(TRNG)和偽隨機(jī)數(shù)生成器(PRNG)。
大部分計(jì)算機(jī)程序和語言中的隨機(jī)函數(shù),的確是偽隨機(jī)數(shù)生成器,它們都是由確定的算法,通過一個(gè)“種子”(比如“時(shí)間”),來產(chǎn)生“看起來隨機(jī)”的結(jié)果。
毫無疑問,任何人只要知道算法和種子,或者之前已經(jīng)產(chǎn)生了的隨機(jī)數(shù),都可能獲得接下來隨機(jī)數(shù)序列的信息。因?yàn)樗鼈兊目深A(yù)測性,在密碼學(xué)上并不安全,所以我們稱其為“偽隨機(jī)”。這種隨機(jī)數(shù),用來讓游戲里的小人跑跑路沒多大問題,如果用來生成比特幣私鑰,那可就太不安全了。
再說說真隨機(jī)數(shù)生成器,中文維基中將“硬件隨機(jī)數(shù)生成器”(HRNG)等同于真隨機(jī)數(shù) 生成器,這其實(shí)并不十分準(zhǔn)確,嚴(yán)格意義上的真隨機(jī)可能僅存在于量子力學(xué)之中,我們當(dāng)前所想要的(或者所能要的),并不是這種隨機(jī)。
我們其實(shí)想要一種不可預(yù)測的、統(tǒng)計(jì)意義上的、密碼學(xué)安全的隨機(jī)數(shù),只要能做到這一點(diǎn)的隨機(jī)數(shù)生成器,都可以稱其為真隨機(jī)數(shù)生成器。這種真隨機(jī),并不一定非得是特殊設(shè)計(jì)的硬件,Linux操作系統(tǒng)內(nèi)核中的隨機(jī)數(shù)生成器(/dev/random),維護(hù)了一個(gè)熵池(搜集硬件噪聲,如:鍵盤、鼠標(biāo)操作、網(wǎng)絡(luò)信號強(qiáng)度變化等),使得它能夠提供最大可能的隨機(jī)數(shù)據(jù)熵,因此同樣是高品質(zhì)的真隨機(jī)數(shù)生成器。
不過/dev/random是阻塞的,也就是說,如果熵池空了,對于/dev/random的讀操作將被掛起,直到收集到足夠的環(huán)境噪聲為止。
因此,在開發(fā)程序時(shí),我們應(yīng)使用/dev/urandom,作為/dev/random的一個(gè)副本,它不會(huì)阻塞,但其輸出的熵可能會(huì)小于/dev/random。
在開發(fā)比特幣應(yīng)用時(shí),應(yīng)該使用何種隨機(jī)數(shù)生成器來生成私鑰呢?
答案很簡單:urandom。永遠(yuǎn)只用urandom。
不要使用任何第三方的隨機(jī)數(shù)解決方案,哪怕是一些高級的安全庫,所提供的聲稱“非常安全”的隨機(jī)函數(shù)。因?yàn)樗鼈兌际怯脩魬B(tài)的密碼學(xué)隨機(jī)數(shù)生成器,而urandom是內(nèi)核態(tài)的隨機(jī)數(shù)生成器,內(nèi)核有權(quán)訪問裸設(shè)備的熵,內(nèi)核可以確保,不在應(yīng)用程序間,共享相同的狀態(tài)。
歷史上,無數(shù)次隨機(jī)數(shù)失敗案例,大多出現(xiàn)在用戶態(tài)的隨機(jī)數(shù)生成器,而且,用戶態(tài)的隨機(jī)數(shù)生成器幾乎總是要依賴于,內(nèi)核態(tài)的隨機(jī)數(shù)生成器(如果不依賴,那風(fēng)險(xiǎn)則更大),除了沒準(zhǔn)兒能簡化您的某些開發(fā)工作,絲毫看不出任何額外的好處,反而增加了因引入第三方代碼,所可能導(dǎo)致的潛在安全風(fēng)險(xiǎn)。
因此,開發(fā)者在需要密碼學(xué)安全的隨機(jī)數(shù)時(shí),應(yīng)使用urandom。