John O'Hanley
Greenhorn
Posts: 24
[Security newbie here:]A web app uses a integer user id. The app needs to place this id on the user's browser as a cookie, but the cookie value needs to be hard to guess, so an integer is out of the question. On the server side, the use of integers saves a lot of storage space.
Summary:
server: integer id (low storage requirements)
cookie: hard-to-guess value, which can be mapped uniquely to the server side integer in a lookup table
How is this handled?

Brian Buege
Author
Ranch Hand
Posts: 42
Originally posted by John O'Hanley:
[Security newbie here:]A web app uses a integer user id. The app needs to place this id on the user's browser as a cookie, but the cookie value needs to be hard to guess, so an integer is out of the question. On the server side, the use of integers saves a lot of storage space.
Summary:
server: integer id (low storage requirements)
cookie: hard-to-guess value, which can be mapped uniquely to the server side integer in a lookup table
How is this handled?

Here's a suggestion that might work, although I'd warn against using one factor authentication (just an ID without a password or something else)
In Java, use the SecureRandom class to generate mostly unpredictable random numbers:

Using the default provider, it takes a long time to create the first instance of SecureRandom, so I'd do it at app startup (or in your servlet init()).
Generating the numbers after that is really fast though.
Generate a random using the mechanism above, then check your HashMap to make sure you haven't already used it...
Then, take the number (we'll call it the REAL number), and add some other random numbers (or random text) before and after it. Separate each number with commas. So, if our REAL number is 5, we might end up with: 52,32,5,77,89. For every string generated, the REAL number should always occupy the same position in the series. For example, all REAL numbers for our app will be stored 3rd in the string.
Then, encrypt this whole string using the JCE and a symmetric algorithm, then BASE64 encode the results. This will give you a long string of garbage. (See the JDK 1.4 security docs for instructions on how to do this).
When the userid is returned to you, decrypt the string, use a tokenizer to grab the third number. This is your userid.
Now that I've told you this, let me say that the more common way to handle this is to compute a message digest of the random number (using something like MD5), Base 64 encode it (which will produce a 16-24 character string), then store that string server side (and client side). This is the mechanism Tomcat uses. Storing strings in a hashmap is not that much less efficient unless you're talking about handling a TON of users (which you might be, I don't know )
Hope this helps!
Let me know if you need further clarification on any of this.... I'm trying to answer as many of these questions as I can!