Correctly generating cryptographically secure pseudorandom numbers (in C)? I am learning about cryptography, purely for my own interest. As part of that, I am implementing a simple one-time-pad toolset in C.

Naturally, I need to generate random numbers to create the pad, and they need to be cryptographically strong. I know about rand(), but from what I can tell it is not strong.

Is there a standard algorithm (or library) that I should be looking at to accomplish this?
Short answer: Don't do this. The security proof for the One Time Pad requires the use of a True Random Bit Generator. The best you can find on a typical multipurpose system without dedicated hardware support for a TRBG is a Cryptographically Secure Random Bit Generator. The difference is that CSRBG is typically a deterministic algorithm that is seeded with good quality entropy the system is able to collect from various states and events. Because of this, using it for generating an OTP would in fact be no more secure than using a black box stream cipher for generating the key stream.

However, for the sake of argument, let's suppose you are implementing an OTP on a *nix based multipurpose system. What is the best you can hope for?


The key will have to be as long as the message and will have to contain random bits, each with full entropy. This means that the key will have to be stored externally after generation. There will be no way of regenerating the exact same key, except by storing it, transferring it over a secure channel and reloading it. If there is any way at all to regenerate the same key stream from a more compact seed or key (even in theory), it is by definition not an OTP.
/dev/urandom is no better than using a stream cipher. It is unblocking exactly because it is based on an algorithm that generates the output from a small seed. In principle, /dev/random should be implemented to return full entropy bits (which is why it is blocking - it always waits for enough entropy to be generated), but, firstly, there is no guarantee that it estimates the entropy of its input correctly, and, secondly, that it manages to extract that entropy in a completely unbiased manner. In fact, if the extraction is accomplished by e.g. hashing the entropy input, it is even highly unlikely that the extracted entropy will be completely unbiased. It will at best be good enough for all practical purposes, but that doesn't include using it for an OTP.