Fortify漏洞之Insecure Randomness(不安全隨機數)


  繼續對Fortify的漏洞進行總結,本篇主要針對  Insecure Randomness  漏洞進行總結,如下:

1、Insecure Randomness(不安全隨機數)

1.1、產生原因:

  成弱隨機數的函數是 random()。 

  電腦是一種具有確定性的機器,因此不可能產生真正的隨機性。偽隨機數生成器 (PRNG) 近似於隨機算法,始於一個能計算后續數值的種子。 

  PRNG 包括兩種類型:統計學的 PRNG 和密碼學的 PRNG。統計學的 PRNG 可提供有用的統計資料,但其輸出結果很容易預測,因此數據流容易復制。若安全性取決於生成數值的不可預測性,則此類型不適用。密碼學的 PRNG 通過可產生較難預測的輸出結果來應對這一問題。為了使加密數值更為安全,必須使攻擊者根本無法、或極不可能將它與真實的隨機數加以區分。通常情況下,如果並未聲明 PRNG 算法帶有加密保護,那么它有可能就是一個統計學的 PRNG,不應在對安全性要求較高的環境中使用,其中隨着它的使用可能會導致嚴重的漏洞(如易於猜測的密碼、可預測的加密密鑰、會話劫持攻擊和 DNS 欺騙)。

 

示例: 下面的代碼可利用統計學的 PRNG 為購買產品后仍在有效期內的收據創建一個 URL。

String GenerateReceiptURL(String baseUrl) {

  Random ranGen = new Random();

  ranGen.setSeed((new Date()).getTime());

  return (baseUrl + ranGen.nextInt(400000000) + ".html");

  這段代碼使用 Random.nextInt() 函數為它所生成的收據頁面生成獨特的標識符。因為 Random.nextInt() 是一個統計學的 PRNG,攻擊者很容易猜到由它所生成的字符串。盡管收據系統的底層設計也存在錯誤,但如果使用了一個不生成可預測收據標識符的隨機數生成器(如密碼學的 PRNG),會更安全一些。

 

1.2、修復方案:

  當不可預測性至關重要時,如大多數對安全性要求較高的環境都采用隨機性,這時可以使用密碼學的 PRNG。不管選擇了哪一種 PRNG,都要始終使用帶有充足熵的數值作為該算法的種子。(諸如當前時間之類的數值只提供很小的熵,因此不應該使用。) 

  Java 語言在 java.security.SecureRandom 中提供了一個加密 PRNG。就像 java.security 中其他以算法為基礎的類那樣,SecureRandom 提供了與某個特定算法集合相關的包,該包可以獨立實現。當使用 SecureRandom.getInstance() 請求一個 SecureRandom 實例時,您可以申請實現某個特定的算法。如果算法可行,那么您可以將它作為 SecureRandom 的對象使用。如果算法不可行,或者您沒有為算法明確特定的實現方法,那么會由系統為您選擇 SecureRandom 的實現方法。 

  Sun 在名為 SHA1PRNG 的 Java 版本中提供了一種單獨實現 SecureRandom 的方式,Sun 將其描述為計算:“SHA-1 可以計算一個真實的隨機種子參數的散列值,同時,該種子參數帶有一個 64 比特的計算器,會在每一次操作后加 1。在 160 比特的 SHA-1 輸出中,只能使用 64 比特的輸出 [1]。” 

  然而,文檔中有關 Sun 的 SHA1PRNG 算法實現細節的相關記錄很少,人們無法了解算法實現中使用的熵的來源,因此也並不清楚輸出中到底存在多少真實的隨機數值。盡管有關 Sun 的實現方法網絡上有各種各樣的猜測,但是有一點無庸置疑,即算法具有很強的加密性,可以在對安全性極為敏感的各種內容中安全地使用。

 

實際解決方案: 

將原本 Random sr = new Random() 換成SecureRandom sr = new SecureRandom() 

 

1.3、預防該漏洞的開發規范:

  1、需要創建隨機數時,不使用 new Random() 的方式創建,可以選擇使用new SecureRandom() 的方式創建。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM