<PackageReference Include="SSH.NET" Version="2023.0.1" />

SecureRandom

using Renci.SshNet.Security.Org.BouncyCastle.Crypto; using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Digests; using Renci.SshNet.Security.Org.BouncyCastle.Crypto.Prng; using Renci.SshNet.Security.Org.BouncyCastle.Utilities; using System; using System.Threading; namespace Renci.SshNet.Security.Org.BouncyCastle.Security { internal class SecureRandom : Random { private static long counter = Times.NanoTime(); private static readonly SecureRandom master = new SecureRandom(new CryptoApiRandomGenerator()); protected readonly IRandomGenerator generator; private static readonly double DoubleScale = System.Math.Pow(2, 64); private static SecureRandom Master => master; private static long NextCounterValue() { return Interlocked.Increment(ref counter); } private static DigestRandomGenerator CreatePrng(IDigest digest, bool autoSeed) { DigestRandomGenerator digestRandomGenerator = new DigestRandomGenerator(digest); if (autoSeed) { digestRandomGenerator.AddSeedMaterial(NextCounterValue()); digestRandomGenerator.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize())); } return digestRandomGenerator; } public static byte[] GetNextBytes(SecureRandom secureRandom, int length) { byte[] array = new byte[length]; secureRandom.NextBytes(array); return array; } public SecureRandom() : this(CreatePrng(new Sha256Digest(), true)) { } public SecureRandom(IRandomGenerator generator) : base(0) { this.generator = generator; } public virtual byte[] GenerateSeed(int length) { return GetNextBytes(Master, length); } public virtual void SetSeed(byte[] seed) { generator.AddSeedMaterial(seed); } public virtual void SetSeed(long seed) { generator.AddSeedMaterial(seed); } public override int Next() { return NextInt() & 2147483647; } public override int Next(int maxValue) { if (maxValue < 2) { if (maxValue < 0) throw new ArgumentOutOfRangeException("maxValue", "cannot be negative"); return 0; } int num; if ((maxValue & (maxValue - 1)) == 0) { num = (NextInt() & 2147483647); return (int)((long)num * (long)maxValue >> 31); } int num2; do { num = (NextInt() & 2147483647); num2 = num % maxValue; } while (num - num2 + (maxValue - 1) < 0); return num2; } public override int Next(int minValue, int maxValue) { if (maxValue <= minValue) { if (maxValue == minValue) return minValue; throw new ArgumentException("maxValue cannot be less than minValue"); } int num = maxValue - minValue; if (num > 0) return minValue + Next(num); int num2; do { num2 = NextInt(); } while (num2 < minValue || num2 >= maxValue); return num2; } public override void NextBytes(byte[] buf) { generator.NextBytes(buf); } public virtual void NextBytes(byte[] buf, int off, int len) { generator.NextBytes(buf, off, len); } public override double NextDouble() { return Convert.ToDouble((ulong)NextLong()) / DoubleScale; } public virtual int NextInt() { byte[] array = new byte[4]; NextBytes(array); return (((((array[0] << 8) | array[1]) << 8) | array[2]) << 8) | array[3]; } public virtual long NextLong() { return (long)(((ulong)(uint)NextInt() << 32) | (uint)NextInt()); } } }