summary refs log tree commit diff
path: root/crypto/src/security/SecureRandom.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/security/SecureRandom.cs')
-rw-r--r--crypto/src/security/SecureRandom.cs34
1 files changed, 18 insertions, 16 deletions
diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs
index ac9d98158..c91b5ee91 100644
--- a/crypto/src/security/SecureRandom.cs
+++ b/crypto/src/security/SecureRandom.cs
@@ -22,13 +22,19 @@ namespace Org.BouncyCastle.Security
 			{
 				if (master[0] == null)
 				{
-					IRandomGenerator gen = sha256Generator;
-					gen = new ReversedWindowGenerator(gen, 32);
-					SecureRandom sr = master[0] = new SecureRandom(gen);
+					SecureRandom sr = master[0] = new SecureRandom(sha256Generator);
 
+					// Even though Ticks has at most 8 or 14 bits of entropy, there's no harm in adding it.
 					sr.SetSeed(DateTime.Now.Ticks);
-					sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(24, true));
-					sr.GenerateSeed(1 + sr.Next(32));
+					// In addition to Ticks and ThreadedSeedGenerator, also seed from CryptoApiRandomGenerator
+					CryptoApiRandomGenerator systemRNG = new CryptoApiRandomGenerator();
+					byte[] systemSeed = new byte[32];
+					systemRNG.NextBytes(systemSeed);
+					sr.SetSeed(systemSeed);
+					Array.Clear(systemSeed,0,systemSeed.Length);
+					// 32 will be enough when ThreadedSeedGenerator is fixed.  Until then, ThreadedSeedGenerator returns low
+					// entropy, and this is not sufficient to be secure. http://www.bouncycastle.org/csharpdevmailarchive/msg00814.html
+					sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(32, true));
 				}
 
 				return master[0];
@@ -38,24 +44,20 @@ namespace Org.BouncyCastle.Security
 		public static SecureRandom GetInstance(
 			string algorithm)
 		{
-			// TODO Compared to JDK, we don't auto-seed if the client forgets - problem?
-
 			// TODO Support all digests more generally, by stripping PRNG and calling DigestUtilities?
 			string drgName = Platform.ToUpperInvariant(algorithm);
 
-			IRandomGenerator drg = null;
 			if (drgName == "SHA1PRNG")
 			{
-				drg = sha1Generator;
+				SecureRandom newPrng = new SecureRandom(sha1Generator);
+				newPrng.SetSeed(GetSeed(20));
+				return newPrng;
 			}
 			else if (drgName == "SHA256PRNG")
 			{
-				drg = sha256Generator;
-			}
-
-			if (drg != null)
-			{
-				return new SecureRandom(drg);
+				SecureRandom newPrng = new SecureRandom(sha256Generator);
+				newPrng.SetSeed(GetSeed(32));
+				return newPrng;
 			}
 
 			throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
@@ -72,7 +74,7 @@ namespace Org.BouncyCastle.Security
 		public SecureRandom()
 			: this(sha1Generator)
         {
-			SetSeed(GetSeed(8));
+			SetSeed(GetSeed(20));	// 20 bytes because this is sha1Generator
 		}
 
 		public SecureRandom(