导致哈希在一定时间后过期

tjm*_*tjm 5 php security hash

我有一种情况,脚本从用户接收一些数据,然后返回一个哈希.在一段时间内,比如说X秒,哈希是有效的,并且当与原始数据一起提供回脚本时,并且在指定的时间范围内,允许访问某些功能.

我这样做是通过在哈希中包含一个时间戳.我可以通过调用say来获取时间戳,floor(time()/X);但是这样,而不是在X秒后过期,在1到X秒之间到期.我通过保存time()%X并将其附加到哈希来解决这个问题,然后当我收到它,解析它并从中减去它时time(),所以我的哈希函数看起来有点像这样:

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;
}
Run Code Online (Sandbox Code Playgroud)

还有盐在那里,但为了清楚起见我删除了它.

这是有效的,但我认为可能有更好的方法来实现我在这之后的想法,并想知道你是否有任何建议.

irc*_*ell 3

好吧,您希望它在一定秒数后过期,对吗?那么,为什么不预先计算过期时间并传递它呢?您只是在谈论正在传输的一些额外字节:

function makeHash() {
    $expire = time() + $this->_cfg['hashexpire'];
    $hash = $expire . ':' . hash_hmac('sha1', $this->_data, $expire);
    return $hash;
}
Run Code Online (Sandbox Code Playgroud)

然后验证:

function verifyHash($hash) {
     if(!strpos($hash, ':')) return false;
     list ($expire, $rawhash) = explode(':', $hash, 2);
     $testhash = hash_hmac('sha1', $this->_data, $expire);
     if ($expire < time() && $testhash == $rawhash) {
         return true;
     }
     return false;
}
Run Code Online (Sandbox Code Playgroud)

请注意,它使用HMAC对数据有效负载进行“签名”。

如果您真的对数据大小很偏执,请在将base_convert($expire, 10, 36)其发送给客户端之前,然后在验证时对其进行解码。

编辑: 当我重读你的问题时,我不确定。您是否正在寻找要生成的哈希值,该哈希值将在$x几秒钟后失效?或者您是否希望在$x几秒的绝对时间窗口内生成相同的哈希值(此后哈希值会发生变化)?如果是之前的情况,上述解决方案将起作用。如果是后者,那么你可以尝试这样的事情:

function makeHash() {
    $time = time();
    $startTime = $time - ($time % $this->_cfg['hashexpire']);
    return hash_hmac('sha1', $this->_data, $startTime);
}
Run Code Online (Sandbox Code Playgroud)

其工作原理是,它与当前窗口的第一个有效秒的时间戳进行散列。这将始终保持不变,因此无需存储它或走得更远......

请注意,生成的哈希值每秒都会更改$_cfg['hashexpire']。但它可能在创建后立即失效。因此,仅当您确实需要时才使用它。}