From a4204754663760e402df1a7752774b7627d717df Mon Sep 17 00:00:00 2001 From: Fasjeit <15075638+Fasjeit@users.noreply.github.com> Date: Fri, 30 Dec 2022 23:18:32 +0300 Subject: [PATCH] Secure random in RandomStrings Adapted code from https://gist.github.com/niik/1017834 --- src/ProtonVPN.Common/Helpers/RandomStrings.cs | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/ProtonVPN.Common/Helpers/RandomStrings.cs b/src/ProtonVPN.Common/Helpers/RandomStrings.cs index 7ce510153..f809dba8c 100644 --- a/src/ProtonVPN.Common/Helpers/RandomStrings.cs +++ b/src/ProtonVPN.Common/Helpers/RandomStrings.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2022 Proton Technologies AG * * This file is part of ProtonVPN. @@ -18,6 +18,7 @@ */ using System; +using System.Security.Cryptography; namespace ProtonVPN.Common.Helpers { @@ -26,7 +27,7 @@ namespace ProtonVPN.Common.Helpers /// public class RandomStrings { - private readonly Random _random = new Random(); + private readonly RNGCryptoServiceProvider _random = new RNGCryptoServiceProvider(); public string RandomString(int length) { @@ -37,10 +38,52 @@ public string RandomString(int length) for (var i = 0; i < randomChars.Length; i++) { - randomChars[i] = chars[_random.Next(chars.Length)]; + randomChars[i] = chars[Next(chars.Length)]; } return new string(randomChars); } + + /// + /// Returns a random number within a specified range. + /// + private int Next(int maxValue) + { + if (maxValue < 0) + { + throw new ArgumentOutOfRangeException(nameof(maxValue)); + } + + if (maxValue == 0) + { + return 0; + } + + while (true) + { + uint rand = GetRandomUInt32(); + + long max = 1 + (long)uint.MaxValue; + + if (rand < max) + { + return (int)(rand % maxValue); + } + } + } + + /// + /// Gets one random unsigned 32bit integer in a thread safe manner. + /// + private uint GetRandomUInt32() + { + lock (this) + { + var buffer = new byte[sizeof(uint)]; + _random.GetBytes(buffer, 0, buffer.Length); + uint rand = BitConverter.ToUInt32(buffer, 0); + return rand; + } + } } }