It seemed to me that the Bouncy Castle SecureRandom
class for C#/.NET only uses DateTime.Now.Ticks
as its seed by default.
I was wrong, but wouldn't that be unsafe to do?
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It only takes a minute to sign up.
Sign up to join this communityIt seemed to me that the Bouncy Castle SecureRandom
class for C#/.NET only uses DateTime.Now.Ticks
as its seed by default.
I was wrong, but wouldn't that be unsafe to do?
Yes, it is unsafe to seed a PRNG with only with the system time. No, that's not all Bouncy Castle's SecureRandom
does.
The SecureRandom
default constructor calls SetSeed(GetSeed(8));
which calls Master.GenerateSeed(length);
which calls SetSeed(DateTime.Now.Ticks);
which is misleading because SetSeed
only adds seed material to an already existing prng (the static instance called Master
). If you look at the static declaration for private static SecureRandom Master
you'll see that it actually seeds itself from a combination of Ticks and ThreadedSeedGenerator.
Why the system time is not enough
Using just the system time would be unsafe. The whole point of a crypto random generator is to be unguessable by an adversary, and by using the system time as a seed to the random number generator, you make it easy for an adversary to guess your seed and hence your random output.
DateTime.Now.Ticks
has precision of 10 million ticks per second. Suppose an attacker knows what time you generated a key, +/- 1 second. They only need to make 20 million guesses ($2^{20}$ or so) in order to guess your random seed. This is likely crackable in a matter of seconds with a modern laptop.
Suppose an attacker has absolutely no idea what time you generated some key. They only know it was after – let's say – the year 2000. Since it's 2014 now, the entire space of 14 years occupies 51-52 bits. log2(10000000*60*60*24*365*14) ~= 51.97
… This means the absolute highest level of entropy that you're likely to have in anything generated from system time is around 51 bits, which is small enough to be easily crackable, and realistically, you'll never even come close to that.
All Bouncy Castle's random generator classes seem to derive from java.security.SecureRandom
, where seed
doesn't mean "initialize state to this". It means "stir in any entropy from this".
That means what they do is not insecure, but shouldn't actually help either, since java.security.SecureRandom
is already seeded with entropy from the system (e.g. /dev/urandom).
I'm assuming the same is true for the C# version, though I don't use C# so I'm not sure.