http://qs321.pair.com?node_id=21720

As some other people have pointed out, it depends on what you intend to do with your random number. More specifically, what is your random number going to protect?

Let me give you a spectrum of examples. Suppose you are building a shopping cart website, and you need to assign a number to each customer who visits. Here are some possibilities (I will discuss the ramifications below):

• Since/If you are using a database (or some other target for DBI), you could just allow an autoincrementing ID to provide your CustomerID.
• You could use a self-built "random" number (like a combination of time + IP address (like Netscape did...OOOPS!))
• You could use some variant of the customer's name or other information for the unique identifier.
• You could use a pseudo-random number, like Perl's built-in rand()
• You could use a "real" random number generator, like Math::TrulyRandom or /dev/random on most UNIX boxes.

The problem with most of these solutions (in descending order of "wrongness") is that they are easy for a cracker/malicious individual to find, guess or generate.

• An incrementing ID is obviously easy to figure out. Make an account, look at your ID, and try the ID below yours.
• Self-built "random" numbers are also pretty easy to figure out. Knowing what time it is, and watching where someone is coming from will give the black hat a very small number of possibilities to try.
• Letting the customer pick the key (either voluntarily, or generated from other information) may be easy to guess, especially when the malcontent can simply look at how you generated his key.
• Pseudo-random numbers are much harder to figure out, but the very definition of pseudo-random numbers means that, given a few numbers generated from the same source, you can (relatively) easily know ALL of the numbers which will follow.
• "Real" random number generators (like Math::TrulyRandom, /dev/random, etc.) get their numbers from a non-deterministic source (like interrupt timing discrepancies). This (theoretically) does not cause any predictability in the output.

Now, the second part of the equation is: "What data are you trying to protect?"

If you are just going to display a random picture (like the "Monk icons" at the upper right of your screen), security is not your concern. Therefore, make the most efficient use of your time and use rand(). If a cracker guesses that the next icon to appear will be vroom's, who cares?

If, however, you will be storing a customer's personal information (especially credit-card numbers) and allowing the user to view that information later...You would be shamefully negligent to use anything less than 128-bit or greater SSL, a truly random number for the CustomerID, strong, cryptographic-quality passwords... (and perhaps even that is not enough).

Here is an example from one of my projects. We are building an e-commerce site which will allow users to order products, entering credit card information for payment. Users may upload graphics to use in the printed product. We have chosen not to allow the user to retrieve credit card data. They may view and edit their uploaded logos.

For SessionIDs and CustomerIDs, we use truly random numbers. Because we do not store intensely sensitive data, we do not need to enforce strict, cryptographic-quality passwords. A Customer's work is important, so we use "real" random numbers to protect the Session. Images (uploaded logos) use auto-incrementing IDs, since they will be hidden behind the CustomerID (and/or SessionID). Customer's logos are their property, so we protect them with the random Customer key, but because logos are (presumably) already publicly available, we do not need the highest level of security for them. When ordering, we transmit credit-card information over SSL and protect the card info appropriately (e.g. NEVER send it via e-mail!), and do not allow a user to see that information again (so we do not have to inflict a random password and other sufficiently paranoid measures upon the hapless visitor). Order confirmation, which uses no sensitive data at all, happens with security-free (what other kind is there?) e-mail.

Security is an ever-present concern in e-commerce. The heart of data security is cryptography. The heart of cryptography is random number generation. The weaker the random numbers, the weaker the cryptography; therefore, the weaker the security. Random numbers having anything to do with security must be the highest-possible quality. Your advice to avoid rand() in CGI is a direct reflection of this security mindset. If you need a random number to keep people out of places where they do not belong, you need the best random number you can get. rand() is not it.

Russ