What's a good token character length for a token-based login? Currently I'm using the following code:

$token = bin2hex(openssl_random_pseudo_bytes(16));

Is 16 sufficient or should I change it with a more adequate number? Should be useful generating randomly the length? And if yes, what should be the range (min and max length)?

  • 5
    OWasp recommend at least 128 bit session IDs, so your current length (16 bytes = 128 bit) should be fine. For future proofing, is there any reason not to double it to 32 bytes? – Luna Jul 22 '15 at 11:38

You're generating 16 bytes which is 128 bits. Modern block and stream ciphers (i.e. AES) have a security margin of 128 bits, so it's reasonable to say that 16 bytes is sufficient.

What I can't say for certain is whether or not openssl_random_pseudo_bytes() is sane enough to rely on.

| improve this answer | |
  • 1
    Thank you, what about generating randomly the length? – user5115459 Jul 23 '15 at 7:03
  • 1
    That doesn't really add any benefit. Pick a length that gives you a comfortable security margin (I typically go for multiples of 3 and employ base64 encoding so it's sufficiently large and doesn't have = padding) and stick with it. – Scott Arciszewski Jul 23 '15 at 10:58

An update for those that find this question since it ranks highly on Google.

If appears from the current PHP documentation that openssl_random_pseudo_bytes can generate a cryptographically strong string, but this is system dependent. You need to pass in a second parameter then check the response like so:

openssl_random_pseudo_bytes( 32, $cstrong );
if ( !$cstrong ) echo 'weak!';

If $cstrong is false the string is not cryptographically strong.


If you're using PHP 7+ you should use random_bytes instead.


Personally I generate tokens as follows:

$token = bin2hex( random_bytes(32) );

This generates a 256 bit string, which is a bit of future proofing.

| improve this answer | |

I think you can use a 64 Bit random value which is encoded as Base64. The possibility to guess the correct token is 1 / 2^64 what is equal to 1 / 18446744073709551616. This is a pretty impressive number and it would be nearly impossible for an attacker to find the correct token with http requests.

| improve this answer | |
  • 2
    OWASP says that 64 bit session identifier is insufficient... – user5115459 Jul 22 '15 at 13:35
  • 2
    The reason 64-bit is insufficient is that you often don't need to find a specific session token and your system may have millions or billions of session tokens. The chance of session tokens natually colliding among users happens at 2^32~4 billion tokens (see birthday problem ). This could be problematic; and it is not unreasonable to expect very large web applications (or attacked web applications) to eventually generate 4+ billion session tokens. – dr jimbob Jul 22 '15 at 16:02
  • 1
    Meanwhile if your application has say 10 million session tokens in existence, and some botnet attacks your application and manages to do a million requests per second, it would take ~21 days to find one of the 10 million existing session tokens. With a 128-bit session token, it would take more than 10 million times the age of the universe (10 million x 13.7 billion years) to find one of the 10 million session tokens. And with 128-bit, you don't run into collision problems until you have about 2^64 tokens out there which is about 2 billion tokens for every human on earth). – dr jimbob Jul 22 '15 at 16:12
  • OWASP says that 64-bit session identifier is insufficient, because it assumes that it has only 32 bit of entropy, eg. 32 bit session identifier encoded as base64. According to OWASP, his 64bit session identifier becomes 128 bit one when it's encoded in hex, so it's exactly the minimum token size recommended. – FINDarkside Nov 1 '18 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.