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;
+ }
+ }
}
}