題:
為什麼不將Math.random()設計為加密安全的?
forest
2018-03-15 11:11:06 UTC
view on stackexchange narkive permalink

JavaScript Math.random()函數旨在返回單個IEEE浮點值 n ,使得0≤ n < 1.眾所周知(至少應該知道)輸出在密碼學上不是安全的。大多數現代實現使用 XorShift128 +算法,該算法可以容易破解。當人們需要更好的隨機性時,錯誤地使用它並不少見,為什麼瀏覽器不將其替換為CSPRNG?我知道至少 Opera可以做到 *。我能想到的唯一理由是XorShift128 +比CSPRNG更快,但是在現代(甚至不是那麼現代)的計算機上,使用ChaCha8或AES-CTR每秒輸出數百兆字節將是微不足道的。這些通常足夠快,以至於只有一個系統的內存速度才能使一個優化的實現成為瓶頸。即使是未優化的ChaCha20實現,在所有架構上都非常快,而ChaCha8的速度要快兩倍以上。

我知道不能將其重新定義為CSPRNG,因為該標準明確地不能保證適用於密碼使用,但瀏覽器供應商自願進行加密似乎沒有任何不利之處。它將在不違反標準的情況下減少大量Web應​​用程序中的錯誤影響(僅要求輸出為近似於最近的 IEEE 754數字),降低性能或破壞兼容性。使用Web應用程序。


編輯:少數人指出,即使標准說您不能依靠它來實現密碼安全性,也有可能導致人們濫用此功能。在我看來,有兩個相反的因素決定了使用CSPRNG是否會帶來淨安全利益:

  1. 錯誤的安全感-否則將使用為此目的設計的功能的人數,例如 window.crypto ,而是改為使用 Math.random(),因為它恰好在其預期的目標平台上是加密安全的。

  2. 機會主義安全性-不知道並使用 Math.random()用於敏感應用程序的人的數量,這些人可以避免自己的錯誤。顯然,最好是教育他們,但這並不總是可能的。

  3. ol>

    可以肯定地假設,有多少個人受到了自己的保護錯誤會大大超過被誤導為錯誤的安全感的人數。

    *正如CodesInChaos指出的那樣,既然Opera是基於Chromium的,那就不再是事實了。

    * sub>


    幾個主要的瀏覽器都有錯誤報告,建議用加密安全的替代方法替換此功能,但未提出建議的安全更改:

for 的參數變化基本上與我的相符。反對它的論點從微基準測試的性能下降(對現實世界幾乎沒有影響)到誤解和神話,例如錯誤的想法,即隨著產生更多的隨機性,CSPRNG隨著時間的推移會變得越來越弱。最後,Chromium創建了一個全新的加密對象,Firefox用XorShift128 +算法替換了其RNG。 Math.random()函數仍然完全可以預測。

評論不作進一步討論;此對話已[移至聊天](https://chat.stackexchange.com/rooms/74736/discussion-on-question-by-forest-why-is-math-random-not-designed-to-be-加密)。
說特徵具有一定的質量意味著義務。義務產生成本,首先是履行義務,其次是使其保持最新狀態,其次是當您發現自己沒有履行義務時。當您必須提供“安全”功能時,尤其如此。
@MichaelK但是,還有很多其他例子是不正確的。您不必在任何地方都說某項功能具有某些特質。保持標準不變,並有機會提高安全性。任何現代C編譯器都是一個很好的例子。您是否認為編譯器支持`FORTIFY_SOURCE`是愚蠢的?為什麼不只是教育人們而不製作脆弱的程序呢?為什麼GCC會保護他們?我不知道任何人的代碼草率,因為他們認為GCC會保護他們,但我知道許多人已經因為GCC的安全措施而獲救。
換句話說,您說的是_fail-safe design_是一件壞事。
@forest機會安全性?我從未想過有人會說的話。
性能也許?獲得加密安全的隨機值比偽隨機值要佔用更多的CPU資源。在設計遊戲(使用C ++)時,我特別必須選擇一種提供出色性能的隨機算法。
眨眼是渲染引擎。V8是Chrome和Opera使用的JavaScript實現。
@Rolfツ已在答案和評論中廣泛討論了此問題。XorShift128 +的性能與ChaCha8(用於返回單個浮點數)相比。
將性能XorShift128 +與ChaCha8進行比較只是性能問題的一部分。CSPRNG必須準備好發射所有安全隨機位之前,必須收集足夠的熵。這會花費大量的時鐘時間。
@JamesKPolk一次只需要128位(ChaCha需要256位,但是只要更改常數,重複兩次密鑰是完全可以接受的)。在加載任何瀏覽器時,系統將可以使用大量的熵。在出於任何原因運行JavaScript解釋器且沒有良好熵來源的微控制器上,它們都可以使用XorShift128 +(因為我不建議更改標準)。
@forest:相當公平,在任何現代平台,台式機或移動設備上,這確實應該不是問題。
十一 答案:
Eric Lippert
2018-03-15 20:10:44 UTC
view on stackexchange narkive permalink

在1990年代中期到後期,我是JScript的實現者之一,並且是ECMA委員會的成員,所以我可以在這裡提供一些歷史觀點。

JavaScript Math.random()函數旨在返回0到1之間的浮點值。眾所周知(至少應該如此),該輸出不是密碼安全的

首先:許多RNG的設計API 很糟糕。 .NET Random類可以以多種方式微不足道地使用以產生相同數量的長序列的事實是可怕的。一種自然使用方式也是錯誤方式的API是“失敗之坑” API;我們希望我們的API是成功的秘訣,自然方法和正確方法是相同的。

我認為可以說,如果我們知道現在所知道的內容,那麼JS隨機API將會有所不同。甚至將名稱更改為“偽隨機”之類的簡單事情也將有所幫助,因為如您所述,在某些情況下,實現細節很重要。在體系結構級別,有充分的理由使您希望 random()成為一個工廠,該工廠返回代表隨機或偽隨機序列的對象,而不是簡單地返回數字。等等。第二課,讓我們記住1990年代JS的基本設計目標是什麼。 在移動鼠標時使猴子跳舞。我們認為內聯表達式腳本是正常的,我們認為兩到十行腳本塊是常見的,有人可能在頁面上寫百行的想法確實非常不尋常。我記得我第一次看到一萬行的JS程序,而我的第一個問題是向我尋求幫助的人,因為與他們的C ++版本相比,它是如此之慢,是“您瘋了嗎?!10KLOC JS ?! “

在JS中,任何人都需要加密隨機性的想法也很瘋狂。您需要猴子的動作來保證不可預測的加密強度嗎?

另外,請記住那是1990年代中期。如果您不打算這樣做,我可以告訴您,就加密而言,這是一個與今天截然不同的世界。請參閱加密的導出

在沒有得到MSLegal團隊大量法律建議的情況下,我什至沒有考慮過[em> 將加密強度隨機性放入瀏覽器附帶的任何內容中。在這個被認為是向國家敵人出口彈藥的世界上,我不想用十英尺高的桿觸碰加密貨幣。從今天的角度來看,這聽起來很瘋狂,但是那就是那個世界

為什麼瀏覽器不將其替換為CSPRNG?

瀏覽器作者不必提供不做任何更改的理由。改變會花費金錢,而且他們會從更好的改變中解脫出來。每項變更都會帶來巨大的機會成本

相反,您不僅需要提供一個論據,不僅要進行更改是一個好主意,而且還應盡可能地利用這些時間。

我知道不能將其重新定義為CSPRNG,因為該標準明確不能保證適用於密碼使用,但無論如何似乎都沒有不利之處

不利之處在於,開發人員在無法可靠地確定其隨機性是否是加密強度的情況下仍然處於靜止狀態。否,甚至更容易陷入依賴標準無法保證的屬性的陷阱。提議的更改實際上並不能解決問題,這是設計問題。

(不討論話題)您是否介意提供參考:“。NET Random類可以以多種方式被濫用以產生相同數目的長序列是可怕的?”:我以前從未聽說過,還是您?指的是經典的“在緊密的循環中創建一千個隨機實例”?
@VisualMelon:在緊密循環中創建數千個實例是經典的。但是,當您同時在兩個線程上使用一個Random實例時,也會出現故障模式。隨機不是線程安全的,在某些情況下,競賽可能導致它永遠返回零!
@VisualMelon:還有更細微的場景。假設您有兩個隨機種子不同的隨機實例。看起來還好吧?但是,假設您隨後以某種方式組合了Random的兩個實例。也許您正在使用它們來產生一系列的模切輥,並將它們成對添加。**這兩個序列是否以某種非隨機的方式相互關聯**?這似乎是合理的。畢竟,他們“並行”運行相同的算法,只是種子不同。
感謝您的闡述:我想我很謹慎,不要嘗試從多個線程使用_any_源代碼,除非為此目的明確記錄了它,所以我永遠不會注意到。我不確定最後一點是不是針對任何“實現”而是其背後的算法:我不認為我們可以要求API設計者對此負責!
我認為,到目前為止,這是最好的答案,尤其是從這樣的權威來源獲得的時候。除非有更好的答案,否則我將目前將此答案標記為已接受。
@EricLippert我不明白您的2個流,它們具有不同的鍵添加在一起的示例。如果它是CSPRNG,那麼我認為應該沒問題。如果它不是CSPRNG(只是計劃PRNG),那麼即使您只有一個實例,也絕對不要將其用於安全性。
@Buge:很容易想像一個(不是很好)的RNG生成整數,並且輸出的最低位是隨機的,但與種子無關。如果您添加兩個這樣的實例的輸出(獨立種子),結果將始終是偶數。(Eric的觀點與安全性無關-我不知道是什麼讓您認為它具有安全性。)
是!為什麼* all *平台上的* all *隨機API如此混亂?我想團隊會“讓實習生這樣做”。
@EricLippert我認為值得為C#的可濫用“ Random”答案提供一個具體示例。像這樣的(偽)代碼:`while(something){int rand = new Random()。nextInt();doSomething(rand);}-之所以失敗,是因為C#的“隨機”使用當前時間和課程分辨率作為種子,因此,如果“ doSomething”很快,您將獲得該序列中第一個數字,無論該時間的種子是什麼,一遍又一遍再次,而不是不同的。(我知道您知道這一點;我正在為那些沒有使用Microsoft進行C#工作的人做解釋)
-1
@MartinBonner我以為Eric的評論是在談論CSPRNG,因為這是security.stackexchange.com,問題和Eric的答案都在談論CSPRNG。
-1
一個很好的,翔實的答案。“機會成本”可能是唯一需要的真實解釋,但是其他所有都是真實的享受
我將提供一個非常相似的答案,該答案基於此處提到的相同主題,基本上,簡短而又令人不滿意的版本是“該規範不需要它,因此實現無需使其在密碼上是隨機的”
-1
@Voo如果“輸出的底端是隨機的,但與種子無關”,則它不是CSPRNG。CSPRNG [要求](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator)如果您不了解種子,則CSPRNG的輸出與真正的隨機性是無法區分的。但是,即使不了解種子,這種不良的PRNG也很容易與真正的隨機性區分開。只需檢查底部是否遵循該模式。
@Buge我當時正在考慮一個隨機性的共享源(例如硬件模塊)。但是您說對了,如果您有兩個序列,那是行不通的。
Philipp
2018-03-15 15:22:47 UTC
view on stackexchange narkive permalink

因為實際上是 Math.random()的一種加密安全替代方案:

window.crypto.getRandomValues(typedArray)

這使開發人員可以使用正確的工具來完成工作。如果要為遊戲生成漂亮的圖片或掉落物品,請使用快速的 Math.random()。當您需要加密安全的隨機數時,請使用價格更高的 window.crypto

您為什麼不使用安全隨機函數進行戰利品掉落?
@xDaizu因為不是每一個戰利品掉落都是一個戰利品盒,有人會用它來製作真實的彩票。
如果您的戰利品需要加密保護,並且*您正在使用客戶端RNG生成戰利品(而不是詢問服務器“我得到了什麼?”),您很可能在做錯事。
這沒有回答問題...森林正在詢問為什麼`Math.Random()`是按其原樣實現的,而不是如何在Javascript中使用CSPRNG
更明確地說,如果您不信任用戶,那麼“ window.crypto”將毫無用處。在這種特定情況下,他們(或他們的用戶代理或他們信任的任何代理)可以在執行之前簡單地用`()=> 0.42`替換它。這些實用程序使用戶(而非您)能夠建立安全性。
@xDaizu在您回复的帖子中回答了您的問題:這是“快速vs [緩慢而昂貴]”的問題
-1
@NH。您在腳本中編寫的所有內容都無濟於事,用戶可以完全控制它
@OrangeDog,是CVE嗎?如果沒有,您可以將您的疑慮作為一個單獨的帖子發表嗎(我們開始與主題有所不同...)
@OrangeDog是的,但這是真的,因為問題是關於客戶端腳本的。與“ Math.random”不是加密安全的事實無關。
Luc
2018-03-15 16:13:53 UTC
view on stackexchange narkive permalink

JavaScript(JS)於1995年發明。

  1. 可能是非法的:加密技術在1995年仍受到嚴格的出口管制,因此,好的CSPRNG甚至可能沒有在瀏覽器中分發是合法的。
  2. 性能:從歷史上看,CSPRNG(加密安全的偽隨機數生成器)比PRNG慢得多,那麼為什麼默認使用CSPRNG?
  3. 沒有安全觀念: 1995年,剛剛發明了SSL。幾乎沒有服務器支持它,互聯網由電話線組成,並且被用於公共論壇( BBS)和 MUD。加密對於情報機構來說是一種東西。
  4. 不需要:由於只是發明了JavaScript,因此尚不存在Web應用程序。它被設計為一種解釋性(因而較慢)的語言,以幫助頁面更加動態。缺省情況下,對隨機函數使用慢速(幾乎不存在)的CSPRNG絕對是沒有道理的。
  5. 如此之少,實際上,別無選擇:直到2013年12月,JavaScript甚至都沒有針對CSPRNG的受普遍支持的API,因此直到幾年前,幾乎不可能在Web應用程序中進行正確的加密。
  6. 一致性:他們沒有將現有功能更改為具有不同的含義,而是使用不同的名稱創建了一個新功能。您現在可以通過 crypto.getRandomValues 訪問CSPRNG。
  7. ol>

    總而言之:既有傳統,又有速度和一致性。不安全的PRNG仍然要快得多,因為您不能假定所有硬件都支持AES,也不依賴於RDRAND的可用性或安全性。

    就我個人而言,我認為是時候將所有隨機函數與CSPRNG交換掉,並將更快,不安全的函數重命名為 fast_insecure_random()之類的東西了。只有科學家或其他需要大量隨機數進行模擬的人才需要使用它們,但是RNG的可預測性不是問題。但是對於具有二十年曆史的功能(現在只有四年(2018年)),我可以理解為什麼我們現在還沒有。

而且Javascript比大多數人認為的要古老得多。自從至少1997年(1.1版)開始就使用了math.random函數。在此之前,甚至沒有人會嘗試使用javascript中的密碼學(SSL直到1995年才問世)。
我不同意最後一句話。儘管單獨使用`crypto.getRandomValues`可能是一個更好的名稱,但是`math.Random`已經存在了很多年,例如`math.RandomCrypto`會是一個更好的選擇,因為它將在下一個列出。到任何API列表中的不安全調用,以及良好的自動完成功能都會在開發人員鍵入`math.rando`時使兩個版本同時出現,這使他們更有可能意識到自己需要使用新的版本。
從語義上講,您的建議是錯誤的。您想要獲得加密上合理的隨機值。不能獲得隨機的加密函數/密碼/等。此外,數學庫僅與數學函數有關。CSPRNG是一種加密功能,因此屬於加密庫。(並且不要忘記添加標準需要所有不同引擎製造商的共識。)
@DanNeely我明白您的觀點,但是不確定如何最好地改變它。隨時編輯!
-1
@DanNeely,您正在嘗試通過技術手段解決人為問題。e.a.人們應該學習在哪裡使用什麼工具,而不是IDE使用一些便利功能來建議正確的工具。(最好是擁有IDE而不是建議正確的IDE,但這取決於IDE)。這也不會幫助所有在瀏覽器/ vim / nano /記事本/石碑/打孔卡/或其他任何文本編輯器或直接輸入方法中編寫JavaScript的人。另外,您還需要聘請很多不容易說服的引擎開發人員。
您可以對@DanNeely提出不同意見,您不在TC39委員會中,也不是與他們的決定進行辯論的正確論壇。FWIW,您可以通過簡單地分配`Math.randomCrypto = function(){const u = new Uint32Array(1);來填充您自己的建議。crypto.getRandomValues(u);返回u [0] / 2 ** 32;}`。當然可以進行優化,但這只是一個示例實現。
Jared Smith
2018-03-15 16:56:31 UTC
view on stackexchange narkive permalink

這個評論太長了。

我相信您的問題有一個錯誤的前提:

在現代(甚至不是那麼現代)的計算機上,使用ChaCha8或AES-CTR每秒輸出數百兆字節將是微不足道的。

我們生活在一個越來越以移動為先的世界中,儘管如今的移動設備功能強大,但它們有兩個重要的限制條件:熱量和電池壽命。與可以輕鬆達到100C的台式機處理器不同,您無法將手從智能手機用戶身上拉下來。手機電池通常只能容納手提電腦的1/3電量(如果幸運的話)。根本沒有充分的理由在不需要時增加額外的熱量產生/功耗。

我懷疑您是否注意到典型代碼(甚至在移動設備上)的加密和非加密RNG之間的性能/功耗差異。您必須使用javascript編寫蒙特卡洛模擬。我們正在談論每個數字大約30個CPU週期。
@CodesInChaos可能是正確的。在撥打電話之前,我想查看分析數據(例如在CRPG的端口上)。但這是一個隱含的前提,即“現在計算機速度很快,所以無關緊要”。
ChaCha8甚至在較舊的處理器上也可以提供每字節3個週期左右的功能,而使用AVX512則可以提供每字節1個週期以下的條件。在高端Haswell處理器上,XorShift128 +的字節數少於1個週期,因此差異不大。我想像將隨機值轉換為適當的浮點並返回它僅比生成隨機值花費更多的周期。
@CodesInChaos人們用JavaScript編寫了Monte Carlo Simulations。
仔細考慮一下,我敢肯定,達到100°C的台式機處理器將“非常糟糕”。筆記本處理器通常可以處理它(如果勉強可以),但是台式機呢?
@CodesInChaos從技術上講,蒙特卡洛不需要加密強度高的RNG。任何體面的RNG都可以使用(例如Mersenne Twister)。
@jb。我的觀點是,加密RNG幾乎可以滿足任何用例的速度,因此應該是默認值。蒙特卡洛模擬是您可能希望以質量換取性能的少數情況之一。
@CodesInChaos鑑於Math.random()僅返回單個浮點值,並且必須為每個新值調用它,所以這是獲取Monte Carlo模擬隨機性的一種相當糟糕的方法,無論XorShift128 +或ChaCha是否用過的。同樣,XorShift128 +的LSB是LFSR,對於這種模擬來說可能不是很好。
@CodesInChaos: *生成*字節中的差異可能很小,但是似乎沒有人提到CSPRNG的更難的部分:收集熵。
瀏覽器可以愉快地使用操作系統產生的隨機數據
-1
@forest:並不是說台式機CPU可以安全地承受更高的溫度(雖然通常不能與移動CPU相似,例如90、95或100C,但不能這樣)。這是因為大多數台式機CPU都安裝了有效的冷卻裝置,因此它們可以運行全傾斜運行的加密操作,並且仍然保持相對較低的溫度,也許是60℃。您根本無法將該冷卻解決方案安裝在手持設備中,其中一個原因是它的重量更大,並且比手機的其餘部分更大,並且只能與通風孔和氣流配合使用,這對於防水手持設備而言可能是不可接受的。袋。
-1
LSerni
2018-03-15 12:15:35 UTC
view on stackexchange narkive permalink

更大的原因是 Math.random()可以替代:請參見Philipp的答案。因此,無論誰需要強大的加密技術,都有可能使用,而那些不需要強大加密技術的人則可以節省時間和(電池)電量。開發人員是否不能以相同的方式更新Math.random(),即使random()成為getRandomValues()的派生產品-以便自動增強大量應用程序? -那麼,我認為這真的沒有信心可以回答,除非是那些做出決定的開發人員(更新:按照Fate的意願,我們確實有這樣的答案)。

原則上-正如您已經說過-沒有充分的理由

此外,大多數開發團隊都有大量積壓的工作要做;甚至像這樣的表面上很小的變化也需要測試,回歸,並違背黃金的“ 如果沒有破裂,請不要解決”規則,這是YAGNI準則的一種更強形式。 / p>

我確信在Mozilla和Google跟踪器上已經對此進行了討論。也許您可以提供一些鏈接來證明這一點?我只對“因為沒有人做過”感到滿意,但是我想看到一些這樣的例子,開發人員不必要地否定了這個想法。
拒絕投票是因為我認為這是可以回答的,並且以粗體顯示該答案的摘要很愚蠢。
@Luc我已經修改了答案以闡明我的意思,並且贊成Philipp的答案,我認為這是對所問問題的正確答案。
Rob
2018-03-16 08:29:02 UTC
view on stackexchange narkive permalink

隨機數和密碼隨機位是完全不同的動物。它們甚至沒有用於相同的目的。如果要在0到42之間均勻分配一個隨機數,則需要一個沒有明顯模式的均勻分佈。請注意,如果將較大的數字修改為較小的數字,則分配的分佈不完全均勻。對於以mod 27為0到31的隨機數,該示例很容易看到。0到4的出現頻率是5到31的兩倍。甚至沒有討論過。一點點的熵會使搜索空間加倍以猜測數字(對於數字的預期用戶)。

當您請求加密隨機位時,您正在尋找N位熵。擁有非顯而易見的模式還不夠好,因為如果發現了生成該函數的函數(無論其卷積如何),那麼從知道該函數的人的角度來看,實際上熵為0位。

一個很好的例子是類似Fortuna的偽隨機數生成器。您使用第一個隨機數的密鑰(其中密碼塊是大數)對數字1進行加密,然後使用第二個隨機數的密鑰對數字2進行加密,依此類推。對於不知道密碼密鑰(K位密鑰)的用戶,一個完美的N位密碼塊將具有該塊的N位熵。

如果從中擴展到一百萬比特的偽隨機數據,那麼如果您繼續使用相同的密鑰K,那麼您仍然只有K比特的熵。換句話說:如果您有一個您知道的一百萬個比特的書是用K下的單個密碼生成的,因此不要嘗試猜測所有密碼流比特。只需堅持猜測密鑰並從中生成密碼流即可。

因此,隨機數生成器通常是一種密碼,可以不斷獲得重新播種,並且具有更大的隨機性。相比之下,一個簡單的[0,1]隨機數生成器的熵不能超過該數中的位數。並且通常具有的奇數分佈也不完全是您想要的。當浮點數僅為32或64位時,加密需要數百位,並且算法本身帶走了很多熵..假設您希望從[0..1]中均勻分佈某些內容,而不是說由隨機位組成的浮點表示。我什至不知道那會有什麼分佈。

richzilla
2018-03-15 16:39:06 UTC
view on stackexchange narkive permalink

您已經親自回答了這個問題:

該標準明確不保證密碼使用的適用性

因此,與其更改實現,

鑑於此,以及更改常用功能的實現的技術開銷以及存在以下事實,即應該著重於教育開發人員選擇“適合工作的工具”。已經有針對該問題的具體解決方案(請參見@Philipps答案),沒有令人信服的理由進行更改。

為什麼選擇DV?匿名小票對任何人都沒有用...
我投票否決,因為這回答了另一個問題。自然,該標準不保證加密安全性。但是,我的問題專門涉及機會安全。這些標準不需要被觸及。技術開銷應該較低,因為瀏覽器已經鏈接到TLS庫。我可能可以編輯一個瀏覽器,以將Math.random()庫用於少於5行的diff。
allo
2018-03-15 15:10:49 UTC
view on stackexchange narkive permalink

編程語言設計需要考慮很多事情。瀏覽器功能非常強大,如今可以優化很多JavaScript。但是,當考慮嵌入式系統時,可能沒有任何好的隨機性來源。例如,有些微控制器在nodeJS(類似)環境中運行。因此,您將需要連接一些可以向引腳提供隨機輸入的設備,以便能夠實現為隨機數提供有力保證的編程語言。而且,您將需要相當多的知識來構建具有足夠隨機性的設備,並以適當的方式處理來自設備的輸入。

運行JavaScript的瀏覽器通常會提供一個很好的隨機性來源,以提供TLS。正如我說過的那樣,無需更改標準,也不必保證API將輸出加密安全的隨機性。
如果API不能保證真正的隨機性,那麼作為開發人員,您不應依賴它。如果開發人員不依賴它,則無需實現它。想像一下,大多數瀏覽器在那裡都具有真正的隨機性。網站會在上面建立東西,因為它在那裡。然後,下一個瀏覽器沒有真正的隨機性。哎呀另一個原因可能是,如果在每個不需要它們的API調用中輸出真正的隨機值,則會消耗更多的熵池並需要更多時間。
但是有些開發人員確實依賴它,不是因為他們認為它是加密安全的,而是因為他們不知道隨機性是如何工作的。也沒有“窮盡熵”之類的東西。單個128位種子可以輸出實際上無限量的不可預測的數據。
@forest的確,將足夠隨機的128位密鑰與足夠好的加密原語結合使用可以生成比我們一生中任何人都可能需要的更多的加密安全偽隨機數據,但是這裡有很多警告。一個簡單的事實是,在包括許多Linux內核在內的某些CSPRNG實現中,熵池並不是一個無限的資源,如果對它們進行足夠的查詢,熵池可能會被耗盡/耗盡。如果需要,鼓勵人們使用`/ dev / urandom`而不是`/ dev / random`之類的東西,但不要假裝`/ dev / random'不會用完。
-1
@forest Pedantry沒有成為您。熵池是自動補充的,但是聲稱它“永不耗盡”就好比說只要有一家雜貨店就不能“耗盡”牛奶。類似地,聲稱“ / dev / random”可能阻止的原因是“愚蠢”,“傳統”並沒有改變從它的讀取可能會長時間阻止的事實,並且實際上已經觀察到在VM之類的情況下會這樣做無需用戶交互或沒有真正的硬件(儘管如今主機通常會向虛擬機提供信息)。對於瀏覽器,任何規範都要求非阻塞熵源嗎?
@CBHacking喝牛奶時,牛奶會從水罐中消失。當您使用熵時,即使從阻塞池開始,池數據仍然存在。唯一改變的是一個整數,它跟踪熵的估計。對於瀏覽器,是必需的。根據規範,許多需要不可預測的隨機數流的操作必須在一定時間段內發生。可能要在不確定的時間段內等待序列號隨機性的TCP實現將是一個壞的實現。
如果要修補內核以強制消除/ dev / random的阻塞行為,它不會阻塞或變成/ dev / zero,就像您期望熵實際上被用完一樣。它仍然是一種完全安全的CSPRNG,儘管它依賴於SHA1的原像抵抗(阻塞池和隱藏輸入池使用SHA1混合,而現代的非阻塞池使用ChaCha20播種,其中輸入中包含48字節隨機數據)池)。因此,我想您可以使用“用盡”一詞,但只能在非常寬泛的意義上使用。從技術上講這是不准確的,並且會神話。
@forest足夠公平,但是行為仍然類似於客戶端應用程序的熵“耗盡”,並且我不會指望SHA1的原像抵抗能夠持續太長時間,此時,非阻塞`/ dev / random`將不再是“完全安全的CSPRNG”。至於瀏覽器,我講的是JS API,而不是內核網絡堆棧(不是瀏覽器!)使用TCP序列號的東西。顯然,對於這個問題,瀏覽器不會使用阻塞池來實現`Math.random()`,只是因為這樣做是愚蠢的,並非沒有可能。
-1
關鍵是,當CSPRNG的狀態洩漏時,您將需要熵以再次將其播種為隨機值。現在,當您查看微控制器時,它是非常確定的。引導後,它的內存看起來總是相同的,這取決於它甚至在請求隨機數時具有相同時鐘週期數的芯片。因此,您需要對其進行播種,否則您的隨機序列總是相同的。
而且由於熵太小,如果您沒有足夠頻繁地植入種子,那麼有人可以使用隨機序列通過蠻力找到CSPRNG的狀態。請記住,不僅MC的狀態非常有限,而且程序本身也不能太複雜,因為程序的空間很小,其餘的代碼可能需要大部分空間。
如果使用`getrandom()`,則除非熵池已初始化,否則它不會返回。完成此操作後,您可以確保不會強制使用池。
@forest在這裡我們不是在談論linux。您的具有簡單javascript實現的微控制器根本沒有內核(在某種意義上就像linux內核)。它直接引導到其nodejs(如)環境中,該環境沒有getgetdom()調用。您需要自己考慮所有提及的因素來實現該調用。
在這種情況下,您可以退回到所需的任何糟糕的PRNG(XorShift128 +,LFSR,LCG等)。無需更改標準即可在一個平台上提供機會安全。
Cort Ammon
2018-03-17 03:04:51 UTC
view on stackexchange narkive permalink

像其他人一樣,我要指出, Math.random()也不是密碼安全的,因為通常不需要它。但是我會進一步爭論說,除非您有充分的理由,否則將密碼安全算法寫入規範中是不明智的。

密碼安全意味著什麼?好吧,總是有一個無聊的定義:“還沒有人知道如何破解它。”但是,當有人破壞它時會發生什麼呢?如果您指定了CSPRNG,則還必須包括一種查詢正在使用哪種算法的方法,或者以其他方式進行查詢,以便最終用戶可以確定所獲得的結果。

導致需要能夠支持多個生成器,以便用戶可以選擇他們信任的生成器。這增加了極大的複雜性。 API中的1行功能突然變成了套件。

此外,當您開始談論加密時,您開始談論嘗試在生成器中確保安全。您提到使用AES生成隨機數:您的AES實現是否需要不受旁通道攻擊的影響?當您編寫一個專門用於提供加密保證的庫時,問這個問題並不是所有不合理的事情。對於一個規範,這可能是非常不合理的。用規範語言來表達對旁通道攻擊的免疫力是非常的措辭。

通過將其放入規格中,您做了什麼?大多數PRNG用戶根本不需要加密保證,因此您只是在浪費CPU週期。那些希望獲得密碼保證的人可能會尋求一個圖書館,該圖書館支持需要具備這種密碼學知識的全套功能,因此他們無論如何都不會信任 Math.random()。剩下的就是您提到的人口統計信息:犯過錯而在不應該使用時使用了工具的人。好吧,我可以從經驗中告訴您,主要的編程語言不是查找錯誤不能錯誤使用的API的地方。他們充滿了“如果執行此操作,這是您自己的錯”的措辭。

此外,請考慮以下問題:如果您使用 Math.random()並假設有加密保證,您將在算法中的某個地方犯另一個致命的加密錯誤的機率是多少? CSPRNG Math.random()可能會提供錯誤的安全感,並且我們可能會發現更多錯誤!

顯然,您不應使用它的_assume_加密屬性。如果需要,可以使用專用的加密API(這也是我建議使用ChaCha8而不是完整回合ChaCha20的原因。請注意,可以對7個回合ChaCha執行加密中斷)。
請參閱我對原始問題的編輯,以澄清此問題。
@forest我看到您的編輯,並且我認為我的最後一段仍然有效。如果有人因為幸運而認為他們的軟件是安全的,而其他人卻對他們的安全性有所考慮,那麼他們就處於無禮的狀態。
Spence
2018-03-22 18:51:10 UTC
view on stackexchange narkive permalink

每個人似乎都在這裡遺漏了一些細微差別:密碼算法要求數字在算法的所有執行過程中在數學和統計上都是隨機的。這意味著,例如在遊戲或動畫中,您可以使用偽隨機數序列,這對於“種類隨機”的數將是完美的。

但是可以操縱或預測,例如種子隨機數(這是Windows隨機函數的默認行為),則該種子實際上是可預測的。如果我可以操縱您的應用程序以重新啟動,然後使用帶種子的隨機數,則可以預測您會選擇哪種“隨機”數。如果有可能,則可以取消加密。第二個關注點可能是某些算法要求在頻譜上保證數字的分佈,而某些偽隨機數生成器無法保證。

密碼隨機數生成器具有大量輸入來創建熵,例如測量麥克風輸入產生的噪聲,一天中的時間滴答聲,內存寄存器的校驗和,序列號等。如果不是不可能的話,盡可能多的輸入將使操作和預測變得異常困難。從密碼學的角度來看,性能不是目標,而是“真正”的隨機性。

因此,根據您的用例,您可能希望對隨機數進行合理的,隨機的,高性能的實現,但是如果要進行複雜處理-hellman密鑰交換,您需要一種加密安全的算法。

Bobby Baucom
2018-03-24 04:02:59 UTC
view on stackexchange narkive permalink

我沒有看到任何人提及(或我只是忽略了)的另一個考慮因素是, Math.random()函數的某些用途實際上與種子相同時依賴於可重複性。時間。現在更改它會破壞這些用途。

所有確定性PRNG都會這樣做,無論是否通過密碼保護。
哪些瀏覽器具備種子生成器的功能?


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...