Initialization Vector Creation - random

My program connects to a server, the public key of the server is already known. The program then encrypts a AES key together with an initialization vector, and sends it to the server. The server decrypts the message and from now on AES is used to encrypt the conversation.
My question is about how to generate the IV. If I go the naive way and seed a pseudo random generator with the current time, an attacker could probably make a few very good guesses about the IV, which is of curse not what I want.
As hardware random generators are not only slow, but also not available everywhere, I'd like to go for a different approach. When the client program is first started, I let the user make a few random mouse moves, just like TrueCrypt does. I now save those "random bits" created by the mouse movement and when I need a generator, I'll use them as a seed. Of course, the random bits have to get updated every time I use them as seed. And this is my question: I thought about just saving the first few random bits generated as the new "random bits". (So they get used to initialize the random engine next time the software starts.) Now I'm not sure if this would be random enough or if pseudo random generators would show guessable patterns here. (I'd probably use std::mt19937 http://en.cppreference.com/w/cpp/numeric/random)
Edit: The chaining mode changes, so I want it to work for the mode with the "highest" requirements. Which would be CBC if I remember correctly.
Please note: The software I'm writing is purely experimental.

Use a cryptography PRNG, just like you do for the key.
On windows use CryptGenRandom/RtlGenRandom and on Linux/Unix use /dev/urandom. Those get seeded by the OS, so you don't need to take care of it.
If you really want to create your own PRNG, look into Fortuna. Don't use a Mersenne twister.

You should clarify which chaining mode you plan to use. The security requirements for the initialization vector strongly depend on that.
For instance, in CBC mode the IV must be unpredictable and unique. For CTR mode, it can must only be unique, not necessarily unpredictable.

Pseudo-random generators are nice for things where you don't want users to be able to predict the outcome (such as dice rolls in games), but worthless for cases where you don't want a computer to be able to compute it. For cryptography, don't use pseudo-randomness at all.
If you want randomness, you need actual random data. As you write, mouse movements are a good source for that. Given that you don't talk about /dev/random, I take it you're running on Windows, which unfortunately doesn't gather randomness while running. So you will have to do this yourself. Depening on the use case, you can run a randomness daemon at startup which keeps gathering random data and allows your program to retrieve it when it is needed, or you can ask the user to make some mouse movements when your program starts.
Or you can decide that if Windows doesn't want you to have real random data, you don't want to use Windows, but I suppose that's not an option. ;-)

Related

What should be used as a PRNG seed?

Most papers either do not even mention it or just say get an "initial vector" from somewhere somehow.
The approach posted in a lot of places is to use system time. However isn't this a serious vulnerability (assuming the algorithms are known)? If the time is known withing a few seconds I estimate (by doing a few trivial tests using QueryPerformanceCounter) there would be less than 24 bits of actual information (quite pathetic). Plus since time has a somewhat predictable nature, one could generate necessary information for a hypothetical attack in advance.
Is there a way to initialize a PRNG and not feel sad?
If you are needing to generate cryptographically secure random numbers, you should almost always use the operating system's CSPRNG; that is, /dev/urandom, CryptGenRandom, getrandom, getentropy, or the like. This will be secure, well-seeded, well-tested, and generally foolproof.
In the unlikely event that you actually need a different CSPRNG, then the PRNG entropy should either be drawn from the system CSPRNG or another CSPRNG that is seeded from the system one. For example, in the event you really need to generate random numbers very quickly and the OS generator is not fast enough, you could use a per-thread CSPRNG seeded from the OS generator.
We assume that an attacker knows how your code is designed and structured, so if you seed a CSPRNG with easily guessable values like the PID, time, or user ID, then it's likely that an attacker will be able to guess future output based on seeing a small amount of output.
If you don't need cryptographic security, you can draw the seed from any source you like, but the OS CSPRNG is not a bad choice if you don't care very much but just want a good seed. For non-cryptographic purposes, I like ChaCha8 (which is a cryptographic algorithm, but with 8 rounds is insufficiently conservative) as my PRNG because it is generally faster than most alternatives, has good statistical properties, and can easily be seeded with any 32- or 64-bit value by just repeating that value as the key. In such a case, as long as the seed is unlikely to repeat, it will probably produce good output.

How do I produce quality random numbers without maintaining internal state?

Normally, you initialize some kind of random number generator object with a seed (usually, the time) at the start of the application and then keep it around and ask it for random numbers. This object is the state.
I have an application that starts, generates one number, then exits. Since the RNG is initialized from the clock, I still have some randomness, but standard RNGs provided by frameworks are not meant to be used like this (asking the first number of each seed), so the quality of the generated numbers is poor. How do I generate quality random numbers without saving the state of the RNG between the invocations of my application?
I'm doing this on Windows, if it matters. Getting extra sources of randomness is fine, but leaving data behind (e.g. writing to disk) is not allowed.
On Windows there is a secure random generator, CryptGenRandom, which will do all that for you. Most languages have a SecureRandom class, dev/random or similar to access it. Other OS's will have similar arrangements. Basically they import entropy from within the system to seed their own generator.
For a more general solution you could use a hardware RNG on a card, such as
the Quantis RNG.

Equivalent of /dev/urandom on Windows?

My application would like to get a random number, preferably with entropy if available, but does not need cryptographic quality, and would like to do ensure that the call does not block if the system entropy pool is depleted (e.g. on a server in a farm).
I am aware of CryptGenRandom, but its behaviour with respect to blocking under adverse entropy conditions is not specified.
On Unix, /dev/urandom supports this use case. Is there equivalent functionality available on Windows? I would prefer to avoid using a non-system RNG simply to get non-blocking semantics.
For a toy application, you could use the standard library function rand(), but the implementation on Windows is of notoriously poor quality. For cryptographically secure random numbers, you can use the rand_s() standard library function.
A better bet is simply to include a suitable pseudo-random number generator in your program. The Mersenne Twister is a good choice IMO, particularly as there are plenty of available implementations (including in the C++11 standard library and in Boost).
If I need non-blocking behaviour on random numbers, I generally pre-generate n numbers and store them in an in memory variable: ie if I know I will need 30 random numbers per second, takes 3 seconds to compute them (including blocks), then I will pre-generate 300 while the main code is loading, store them in an array or vector and use them at need; whilst using them I generate another one on a separate thread every time I use one up, replacing the utilised random number with the newly generated one and moving on to the next one in the list, that way when I hit the limit (in this case 300) I know when I can simply start again at the start of my array/vector/list and all the random numbers are fresh and will be non-blocking (as they are pre-generated).
This means you can use any random number generator you like and not worry about blocking behaviour, however it has the expense of utilising more ram, negligible however for the sort of coding I need random numbers for.
Hope this helps, as I couldn't fit this all into a comment:)
You could wait for one good seed full of entropy and follow GMasucci advice to pre-generate a long list of random numbers.
Unless your system is already compromised it seems that a good seed it's good enough to generate a series of non-related numbers as discussed in http://www.2uo.de/myths-about-urandom/
From the discussion I get that a continuous feed of ("true"/"fresh") random numbers it's only needed if your system state (your sources of entropy are known and the attacker knows their current state) it is compromised at some point. After feeding your block cypher more randomness, the predictability of its output will get lower.
Source of seeds? Two or more pieces of trusted software that are less likely to be already compromised. I try to blur out the predictability of the functions that use time functions as seed: local rand_function() + some variable delay + mysql's rand().
From there, a list of pseudo-random numbers generated by some good library.

Is it more secure to use a cryptographically secure PRNG to generate passwords?

We have a script to stand up a new web server at my job. The script involves creating a number of accounts to run services, app pools etc.
We needed to create a password for each of these users -- i.e. generate a 32-or-so-character ASCII string to be used as a logon password.
We had a disagreement as to whether one ought to use a cryptographically-secure PRNG for this job, or whether using a non-cryptographically secure PRNG (with a time-dependent seed) would suffice (we work in .NET, so the concrete decision was between generating strings with System.Random and using a RNGCryptoServiceProvider -- however, this is not a language-specific issue).
Must one use cryptographically-secure randomness for generating passwords, or is a sensibly-seeded plain PRNG sufficient?
In many cases, an attacker can easily recover the state of a (non-cryptographic) random number generator from a few output values – without knowing anything about the seed. After that, it's trivial to predict all future and all previous random numbers.
How many outputs are required for this depends on the algorithm. In the case of a linear congruential generator, such as Java's java.util.Random, the state can be recovered from two outputs. For Mersenne Twister, used in PHP and Python among others, you need to obtain 624 outputs. I'm not familiar with .NET, but I'd think it's a similar story.
There is no complex math involved at all. See for yourself:
Linear congruential generator, part 1
Linear congruential generator, part 2
Mersenne Twister, part 1
Mersenne Twister, part 2
Conclusion: Use a cryptographically secure random number generator for anything that has to do with security.
Theoretically, if an attacker knows your exact algorithm for producing random passwords (say, he got his hands on your code), and he knows that you seeded your PRNG with system time, then he could reproduce the passwords generated at each instant in time to whatever resolution your system timer has, reducing his brute-force password search by orders of magnitude.
System timer has essentially zero entropy. If you seed a RNG with something like /dev/random (on Linux/ OSX) or CryptGenRandom (Windows), then the fact that the PRNG itself is not CS probably won't matter, because an attacker would have to get more than one password's worth of data to be able to crack it. But then if you're already using a CSPRNG to seed a PRNG, you might as well just use it to create the password in the first place.
Non-CS PRNGs are fast, and great for things like game simulations and Monte Carlo integration, but security passwords, nonces, keys, and such should really use secure algorithms.
That said, security, as always, is not a "yes/no" question--it's always a matter of cost/benefit. The right choices always depend on the value of what you're protecting, the cost of your efforts to protect it, your likely attackers, the cost of failure, and so on, so there's no single right choice for every situation.

Is user delay between random takes is good improvement for PRNG?

I thought that for making random choices for example for next track in a player or next page in the browser it could be possible to use time as 'natural phenomenon', for example decent RPNG just can continuously get next random number without program request (for example in a thread every several milliseconds or event more often) and when the time comes (based on the user decision), the choice will be naturally affected by this user delay.
Is this approach is good enough and how can it be tested? The problem for testing manually is that I can not wait that long in real world to save enough random numbers to feed them to some test program. Any artificial attempt to speed this up will make the method itself invalid.
Thanks
A good random number generator really doesn't need improvement, and even if it did, it isn't clear that user input timing would help.
Could a user ever detect a pattern in tracks selected by an LCG? Whatever your platform, its likely that its built-in random() function would be good enough (that is, it would appear completely random to a user).
If you are still worried, however, use a cryptographic quality RNG, seeded with data from the dedicated source of randomness on your system. Nowadays, many of these system RNGs use truly random bits generated through quantum events in hardware. However, they can be slow to produce bits, so its best to use them as a seed for a fast, algorithmic PRNG.
Now, if you aren't convinced these approaches are good enough, you should be very skeptical that the timing of user typing is a good source. The keys that are pressed by users are highly predictable, given the limited vocabulary in use and the patterns that tend to appear within that limited set of words. This predictability in letter sequences leads to a high degree of predictability in timing between key presses.
I know that a lot of security programs use this technique during key generation. I don't think that it is pure snake oil, but it could be a placebo to placate users. A good product will depend on the system RNG.
Acquiring the time information that you describe can indeed add entropy to a PRNG. However, from your description of your intended applications, I don't think you need it. For "random choices for example for next track in a player or next page in the browser", a trivial, unmodified PRNG is fine. For security applications such as nonces, etc. it is much more important.
Anyway, you should read about PRNG entropy sources.
I wouldn't improve PRNGs with user delays, mostly because they're quite regular: you type at around the same speed, and it takes too long to measure the delay between a click and another (assuming normal usage). I'd rather use other user-triggered events: pressed keys, distance between each click, position of the mouse at given moments.

Resources