I have a situation where a script receives some data from the user, it then returns a hash. For a certain amount of time, say X seconds, the hash is valid and when supplied back to the script along with the original data and within the specified timeframe, certain functions are allowed to be accessed.
I am doing this by including a timestamp in the hash. I can get a timestamp by calling say floor(time()/X); but this, instead of expiring after X seconds, expires anywhere between 1 and X seconds. I have got around this by saving time()%X and appending it to the hash, then when I receive it back, parsing it out and subtracting it from time(), so my hash function looks a little like this:
function hash($oldhash='') {
static $hash;
if(!$hash) {
$time = time();
$expoff = explode('!', $oldhash, 2);
$expoff = $expoff[0] ? $expoff[0] : $time%$this->_cfg['hashexpire'];
$hash = $expoff.'!'.sha1($this->_data.floor(($time-$expoff)/$this->_cfg['hashexpire']));
}
return $hash;
}
Theres also a salt in there but i removed it for clarity.
This works, but I’m thinking there is probably a better way to achieve what I am after here and wonder if you have any suggestions.
Well, you want it to expire after a certain number of seconds, correct? Well, why not pre-compute the expire time, and pass that instead? You’re only talking a few extra bytes being transferred:
Then to verify:
Note that it’s using a HMAC to “sign” the data payload.
And if you’re really paranoid about the data size, just
base_convert($expire, 10, 36)prior to sending it to the client, and then decode it when verifying it.Edit: As I’m rereading your question, I’m not sure. Are you looking for a hash to be generated that will be invalid after
$xseconds? Or are you looking to generate the same hash for a absolute time window of$xseconds (after which the hash changes)? If the prior, the above solution will work. If the later, then you could try something like this:The reason this works, is that it hashes with the timestamp of the first valid second of the present window. That will always stay the same, so there’s no need to store it or go any farther…
Note that the generated hash will change only every
$_cfg['hashexpire']seconds. But it could be invalidated the very second after it was created. So only use this if that’s really what you need.}