Browse Source

src: seed V8's random number generator at startup

The default entropy source is /dev/urandom on UNIX platforms, which is
okay but we can do better by seeding it from OpenSSL's entropy pool.

On Windows we can certainly do better; on that platform, V8 seeds the
random number generator using only the current system time.

Fixes #6250.

NB: This is a back-port of commit 7ac2391 from the master branch that
for some reason never got back-ported to the v0.10 branch.

The default on UNIX platforms in v0.10 is different and arguably worse
than it is with master: if no entropy source is provided, V8 3.14 calls
srandom() with a xor of the PID and the current time in microseconds.

That means that on systems with a coarse system clock, the initial
state of the PRNG may be easily guessable.

The situation on Windows is even more dire because there the PRNG is
seeded with only the current time... in milliseconds.
v0.10.27-release
Ben Noordhuis 11 years ago
committed by Fedor Indutny
parent
commit
70f198ddb1
  1. 6
      src/node.cc
  2. 8
      src/node_crypto.cc
  3. 1
      src/node_crypto.h

6
src/node.cc

@ -3057,6 +3057,12 @@ int Start(int argc, char *argv[]) {
Init(argc, argv_copy);
V8::Initialize();
#if HAVE_OPENSSL
// V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool.
V8::SetEntropySource(crypto::EntropySource);
#endif
{
Locker locker;
HandleScope handle_scope;

8
src/node_crypto.cc

@ -157,6 +157,14 @@ Handle<Value> ThrowCryptoTypeError(unsigned long err) {
}
bool EntropySource(unsigned char* buffer, size_t length) {
// RAND_bytes() can return 0 to indicate that the entropy data is not truly
// random. That's okay, it's still better than V8's stock source of entropy,
// which is /dev/urandom on UNIX platforms and the current time on Windows.
return RAND_bytes(buffer, length) != -1;
}
void SecureContext::Initialize(Handle<Object> target) {
HandleScope scope;

1
src/node_crypto.h

@ -280,6 +280,7 @@ class Connection : ObjectWrap {
friend class SecureContext;
};
bool EntropySource(unsigned char* buffer, size_t length);
void InitCrypto(v8::Handle<v8::Object> target);
} // namespace crypto

Loading…
Cancel
Save