Reputation: 3166
Is it possible to generate a token with a built-in expiration period? And if so, what would be the most secure way to do it?
To achieve this the generation datetime has to be encoded in the token in a secure matter.
Upvotes: 1
Views: 988
Reputation: 751
Sometimes I needed this without any database in the backend.
You can generate random bytes with a secure entropy source (random_bytes for PHP 7, openssl_random_pseudo_bytes or reading /dev/urandom file directly), then pack the timestamp to bytes: pack('N', time());
append it to the random bytes and then sign it with HMAC server's key.
Token creation:
$random = random_bytes(8);
$time = pack('N', time());
$token = $time . $random;
$sign = hash_hmac('sha256', $token, $SERVER_KEY, true);
$token = $sign . $token;
echo $token;
For check:
if (strlen($token) !== 44)
die('Invalid token'); // 32 byte of hash, 4 of timestamp, 8 of random
$hash = substr($token, 0, 32);
$token = substr($token, 32);
$sign = hash_hmac('sha256', $token, $SERVER_KEY, true);
if ($hash !== $sign)
die('Invalid token');
$time = unpack('N', substr($token, 0, 4));
if (time() - $time[1] > $EXPIRY_SECONDS)
die('Expired token');
//valid
Obviously there are a lot of other security aspects to keep in mind, such as Reply-attack that needs store used tokens at least until they expire. For packing and unpacking the time I've used N flag which is for Big-Endian, but you can also use V for Little-Endian or L for machine-dependent order.
Upvotes: 1
Reputation: 3272
Why not use a JWT in it's simplest form with not befor and not after time defined , you can leave out the claims... JWT fits the bill completely here..
Upvotes: 2
Reputation: 3470
If you sign your token, say with HMAC, you can add anything you want to it, for example an expiration date, or a creation date and check how old it is when you process it to determine if it has expired. The HMAC guarantees that the token can't be modified unless your secret has been compromised.
Upvotes: 0