6

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

<?php        
$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)?

1
  • 6
    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, 2015 at 11:38

3 Answers 3

1

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.

2
  • 1
    Thank you, what about generating randomly the length? Jul 23, 2015 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. Jul 23, 2015 at 10:58
4

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.

http://php.net/manual/en/function.openssl-random-pseudo-bytes.php

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

http://php.net/manual/en/function.random-bytes.php

Personally I generate tokens as follows:

$token = bin2hex( random_bytes(32) );

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

1

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.

4
  • 2
    OWASP says that 64 bit session identifier is insufficient... Jul 22, 2015 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, 2015 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, 2015 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. Nov 1, 2018 at 12:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .