2022年8月18日 星期四

[研究]Fortify SCA : Insecure Randomness 之解決

[研究]Fortify SCA : Insecure Randomness 之解決

2022-08-18

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C#

********************************************************************************



********************************************************************************

Abstract: 由 Next() 實作的亂數產生器無法抵擋加密攻擊。

Explanation: 在安全性要求較高的環境中,將一個能夠產生可預測值的函數當作隨機來源使用時,會產生 Insecure Randomness 錯誤。

********************************************************************************

Recommendations:

當不可預測性至關重要時 (例如大多數對安全性要求較高的環境都採用隨機性),請使用加密型 PRNG。不管您選擇哪一種 PRNG,請務必使用擁有足夠複雜度 (entropy) 的值來進行演算。(像當前值的複雜度就很低,因此不宜使用。)

.NET 框架在 System.Security.Cryptography.RandomNumberGenerator 中提供了加密式的 PRNG。就像在 System.Security 中,和其他以演算法為基礎的類別一樣,RandomNumberGenerator 在特定演算法組合中提供了獨立執行的封裝程式。當您使用 RandomNumberGenerator.Create() 要求 RandomNumberGenerator 物件的實例,您可以要求執行特定的演算法。如果演算法是可行的,那麼會將它當作 RandomNumberGenerator 的物件使用。如果演算法不可行,或者您沒有指定特定的實作方式,那麼您會得到由系統所選擇的 RandomNumberGenerator 實作方式。 

Microsoft 提供一種 RandomNumberGenerator 執行方式 (包括名為RNGCryptoServiceProvider 的.NET 框架),以下為 Microsoft 的描述:

「為了產生隨機數字產生器的種子,呼叫的應用程式會提供一些來自滑鼠或鍵盤即時輸入的位元。這些位元會加入到儲存的種子、各種系統資料和使用者資料中,例如:程序識別碼、執行緒識別碼、系統時鐘、系統時間、系統計數器、記憶體狀態、可用磁碟叢集,經 hash 處理的使用者環境區塊等。這個結果是經 SHA-1 hash 處理,該輸出是用來產生 RC4 串流的種子。這個種子會用作隨機串流,且用來更新已儲存的種子。」 

不過,Microsoft 的 RNGCryptoServiceProvider 演算法的執行細節在文件中未明確地記錄,而且在哪個環境下執行使用哪個來源的熵很不清楚,因此也不知道在輸出中存在著多少真實的隨機數值。雖然網路上對 Microsoft 的應用有許多臆測,但仍然沒有證據來反駁下列主張:演算法有很強的加密性,而且能安全在安全性要求較高的環境中使用。

References:

[1] RandomNumberGenerator Class, Microsoft, https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator?view=netframework-4.8

[2] System.Security.Cryptography Namespace, Microsoft, https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography?view=netframework-4.8

********************************************************************************

修改如下

參考

https://stackoverflow.com/questions/6299197/rngcryptoserviceprovider-generate-number-in-a-range-faster-and-retain-distribu

Default.aspx.cs

using System;
using System.Security.Cryptography;

namespace WebApplication19
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            int min = 4;
            int max = 8;
            //Random random = new Random();

            // Fortify SCA : Insecure Randomness
            //int saltSize = random.Next(min, max);

            // 加密式的 PRNG(Pseudo-Random Number Generator).
            // https://docs.microsoft.com/zh-tw/dotnet/fundamentals/code-analysis/quality-rules/ca5394
            // GetInt32 要 Core 3.0, Core 3.1, 5, 6, 7 Preview 7 或 .NET Standard	2.1
            // https://docs.microsoft.com/zh-tw/dotnet/api/system.security.cryptography.randomnumbergenerator.getint32?view=net-6.0#system-security-cryptography-randomnumbergenerator-getint32(system-int32-system-int32)
            // var sensitiveVariable = RandomNumberGenerator.GetInt32(toExclusive);

            using (var rng = new RNGCryptoServiceProvider())
            {
                var data = new byte[4];
                rng.GetBytes(data);

                int generatedValue = Math.Abs(BitConverter.ToInt32(data, startIndex: 0));

                int diff = max - min;
                int mod = generatedValue % diff;
                int normalizedNumber = min + mod;

                Label1.Text= normalizedNumber.ToString();
            }
        }
    }
}

掃描結果,沒有被報告了。



(完)

相關

沒有留言:

張貼留言