Here is code for secure, easy, but a little bit more expensive session identifiers.
import java.security.SecureRandom;publicfinalclassSessionIdentifierGenerator{privateSecureRandom random =newSecureRandom();publicString nextSessionId(){returnnewBigInteger(130, random).toString(32);}}
This works by choosing 130 bits from a cryptographically secure random bit generator, and encoding them in base-32. 128 bits is considered to be cryptographically strong, but each digit in a base 32 number can encode 5 bits, so 128 is rounded up to the next multiple of 5. This encoding is compact and efficient, with 5 random bits per character. Compare this to a random UUID, which only has 3.4 bits per character in standard layout, and only 122 random bits in total.
If you allow session identifiers to be easily guessable (too short, flawed random number generator, etc.), attackers can hijack other\'s sessions. Note that SecureRandom
objects are expensive to initialize, so you\'ll want to keep one around and reuse it.
Here is alternative code for cheap, insecure random alpha-numeric strings. You can tweak the \"symbols\" if you want to use more characters.
publicclassRandomString{privatestaticfinalchar[] symbols;static{StringBuilder tmp =newStringBuilder();for(char ch =\'0\'; ch <=\'9\';++ch)
tmp.append(ch);for(char ch =\'a\'; ch <=\'z\';++ch)
tmp.append(ch);
symbols = tmp.toString().toCharArray();}privatefinalRandom random =newRandom();privatefinalchar[] buf;publicRandomString(int length){if(length <1)thrownewIllegalArgumentException(\"length < 1: \"+ length);
buf =newchar[length];}publicString nextString(){for(int idx =0; idx < buf.length;++idx)
buf[idx]= symbols[random.nextInt(symbols.length)];returnnewString(buf);}}