Of the use of unpredictableSeed
cym13 via Digitalmars-d
digitalmars-d at puremagic.com
Sun Feb 26 16:10:31 PST 2017
On Sunday, 26 February 2017 at 22:56:14 UTC, Nick Sabalausky
(Abscissa) wrote:
> On 02/26/2017 01:23 PM, cym13 wrote:
>> Hi,
>>
>> I found many times that people use unpredictableSeed in
>> combination with
>> normal PRNG for cryptographic purpose. Some even go as far as
>> reseeding
>> at each call to try making it more secure.
>>
>> It is a dangerous practice, most PRNG are not designed with
>> security
>> (and unpredictability) in mind, and unpredictableSeed was
>> definitely not
>> designed with security in mind (or it failed heavily at it).
>> It's a good
>> tool when one needs randomness, not security.
>>
>> I wrote a blog post to present exactly why this is a bad idea
>> and how it
>> could be exploited [1].
>>
>> The best would be to add a standard CSPRNG interface to Phobos
>> but we
>> aren't there yet.
>>
>> [1]: https://cym13.github.io/article/unpredictableSeed.html
>
> FWIW, DAuth[1] uses, and offers, an implementation of
> Hash_DRBG, a well-known and established CSPRNG algorithm. It's
> entropy source (not exactly the same as a seed, but basically
> the CSPRNG equivalent) is customizable, but by default, it uses
> _RtlGenRandom on Windows (the same source used by the
> CryptGenRandom algorithms) and '/dev/urandom' on Posix:
>
> https://github.com/Abscissa/DAuth/blob/master/src/dauth/hashdrbg.d
>
> [1] Ugh, still haven't gotten around to finishing DAuth's new
> version, renamed "InstaUser".
And it is very interesting to note that you fall into the very
exact problem I am describing in my post if it weren't that your
default PRNG isn't seedable. Use any other PRNG and you are
vulnerable (if I read it correctly, I haven't spent much time on
that).
From random.d, the function randomToken calls randomBytes which
inits a new PRNG which is seeded with unpredictableSeed which
becomes the actual PRNG used:
string randomToken(Rand = DefaultCryptoRand)(size_t strength =
defaultTokenStrength)
if(isDAuthRandom!Rand)
{
return TokenBase64.encode( randomBytes!Rand(strength) );
}
ubyte[] randomBytes(Rand = DefaultCryptoRand)(size_t numBytes)
if(isDAuthRandom!Rand)
{
Rand rand;
rand.initRand();
return randomBytes(numBytes, rand);
}
private void initRand(Rand)(ref Rand rand)
if(isDAuthRandom!Rand)
{
static if(isSeedable!Rand)
rand.seed(unpredictableSeed);
}
The only thing that saves you here is that your DefaultCryptoRand
isn't seedable. Note that I'm not saying that to bash you or
anything, it just happens to show well why I think my article was
necessary.
More information about the Digitalmars-d
mailing list