4

I want to create my computer passwords with a RNG, but I am thinking about one thing: I would use python to write that script and the RNG is controlled by one seed, most likely the time. If I would generate my passwords with a RNG that is seeded with the time and someone knows about it, he could try to brute-force the generated passwords by using the time when I possibly created the passwords.

To put it short, in my opinion time is no good seed for a RNG if the output should stay secret, but what are good seeds for an RNG? I already heard of ideas like reading allocated memory (if it was just allocated, it should contain random bytes), using the current PID or using the last bits of the mouse cursor position. Which of these ideas (or other ideas) is really complete random?

3

This depends on the platform.

As a general case, you should consider using the OpenSSL bindings to use OpenSSL's RAND_* API. Do make sure to seed it correctly. Not reading the OpenSSL documentation will cause a security compromise on virtually all operating systems due to improper RNG seed. Even “big ones” have been bitten by this.

On Unix-like operating systems including BSD, the Hurd and Mac OS X, you should read from /dev/arandom (if it exists), or /dev/urandom (if it exists), or /dev/random (only if none of the other two exist). If none of these ① exist and ② are character devices, stop with an error to prevent compromise. You really do not want to “invent” an RNG/seeding scheme yourself!

On Windows® systems… first consider if you really want to do this. This is already a potential security compromise. Then, read from /dev/urandom if it exists (Cygwin), or use the CryptGenRandom API. I'm not sure there are Python bindings for it, but it's not hard to do in C, and can be made into a compiled Python module. Maybe with FFI…

When using OpenSSL, do consider to set RANDFILE to keep a seed across program invocations, especially on Windows®. Consider preseeding this from known good entropy. Maybe mixing stuff from random.org, randomnumbers.info or fourmilab.ch's Hotbits service (but, again, do not only take from there, as it's transmitted over the network). Be aware that the RANDFILE is not handled properly by OpenSSL by default: instead of read+RAND_add+write+close on program start, it's normally read at program start and written only at program end; this is better but only if your program (and all other programs using it) is not running more than one instance at any given time.


Do not use any of those:

  • Process ID
  • Time
  • Mouse position
  • Screen content
  • Content of “uninitialised” memory – it is often not uninitialised (even malloc() results, which the C library may not initialise, is initialised by the OS for the sole reason to clear what was in there before (e.g. from another process), and the simplest way to clear it is to zero it out), and if it is, this is normally Undefined Behaviour, which may lead to all sorts of mayhem

It is true that these are (some of the) input sources used by the OS and/or OpenSSL for their RNG implementations. But these people know (more or less, but a bit more than you) what they are doing, and, far more importantly, they are not the only sources. They are all not secrets, and an attacker can experiment with them. More importantly, their value range is not great. Also, do not write any “keyboard input” code (values and timing) yourself. The OS handles keypress-to-entropy conversion itself, normally. Just ask the OS for good entropy, and error out if there isn't any.

Do not use the system's hardware random number generator as only source! They can be compromised. Also, it may not even exist, or access be prohibited (think virtual machines).

Mixing any of these into a pool is good – but then again, the OS will do a much better job at that than your user-space application.

  • 1
    Thank you very much for your detailed answer. There's still one thing I don't understand: On Windows® systems… first consider if you really want to do this. This is already a potential security compromise.. Do you mean that Windows is insecure in general? Also, what do you think about using fresh allocated memory (it should contain nearly random bytes)? That could be a good addition to your suggested mix of OS random bytes and library RNGs, OpenSSL as you suggested. – Sirac May 30 '14 at 20:50
  • 2
    Yes, Windows® is much less secure in general: more attack surface, more viruses, less isolation of user processes, etc. Also, freshly allocated memory (coming from the OS) is normally all 00 bytes. – mirabilos May 30 '14 at 21:44
  • Ok, I understand this, but when it comes to allocated memory, it should not be all 0x00 bytes, here a snippet of the documentation of void* malloc(int size): ` The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.`, so how about to XOR your already computed seed with the hash of the allocated memory, to make if more difficult to recreate to circumstances that led to the seed? (As far as I understood, XORing random bytes with something (even plaintext) will result in plaintext) – Sirac May 30 '14 at 21:56
  • I agree with you that I should not write any RNG code, I simply lack the skills and the mathematical understanding needed for that. But when it comes to my understanding of XORing, I still believe I am right. If I would give you a lot of plaintext XORed with random bytes, could you get information about that plaintext. Also, if you XOR a known byte with a random byte, you cannot know the result, all possible results have the same chance. – Sirac May 30 '14 at 22:17
  • No, I would not get any information about any plaintext, if you XOR it with (really) random bytes. (That being said, XOR is an acceptable mixing in some conditions, but not generally. You want to use algorithms that preserve entropy better, and circulate it around the buffer.) This is a construction commonly found in stream ciphers. – mirabilos May 30 '14 at 22:29
2

Python provides the function os.urandom() to read bytes from the OS CSPRNG mentioned by Stephen Touset above.

For the more appealing random module API, it also provides the class random.SystemRandom() that uses the same source.

There's no reason to do anything more complicated.

I already heard of ideas like reading allocated memory (if it was just allocated, it should contain random bytes) ...

By the way, this led to one of the more infamous security disasters in recent memory. (Well, before 2013, anyway.) OpenSSL's CSPRNG used uninitialized memory as a questionable extra source of "entropy" -- not the only source, of course, but mixing it in couldn't hurt, right? In 2006, a Debian developer got sick of the Valgrind warnings this produced and disabled that line of code. Misinterpreting OpenSSL's unintuitive code, they also inadvertently disabled every other source of entropy except for the PID, so for two years users of Debian, Ubuntu and company were getting only 32,767 different "random" streams.

  • +1 from me for providing the library reference, which I missed. Thanks. – mirabilos May 30 '14 at 23:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.