如何改进PHP的NONCE库?

时间:2012-07-30 17:59:50

标签: php security

这是我第一次使用nonces,所以我从http://fullthrottledevelopment.com/php-nonce-library下载了脚本。我不喜欢这些代码,特别是因为合法请求被视为无效,因为该函数在定义的时间间隔内工作(默认为300秒)。

例如,我们可以在生成随机数的300秒内299秒,因此现时只能工作1秒钟。

我将库修改为以下功能。我所做的是使用nonce_create(time()-NONCE_DURATION)==$nonce检查当前间隔和上一个间隔。有没有办法进一步改进功能?:

define( 'NONCE_UNIQUE_KEY' , '123123' );
define( 'NONCE_DURATION' , 300 );

function nonce_create($time=false){
    if(!$time)
        $time=time();
    $i=ceil($time/(NONCE_DURATION));
    return substr(md5($i.NONCE_UNIQUE_KEY),-12,10);
}

function nonce_is_valid($nonce){
    if (nonce_create()==$nonce || nonce_create(time()-NONCE_DURATION)==$nonce)
        return true;
    return false;
}

另外,我对原始库有两个问题:

  1. 为什么不使用NONCE_UNIQUE_KEY?作者是否完全忘了?
  2. 为什么作者在这里除以2:$i = ceil( time() / ( FT_NONCE_DURATION / 2 ) );,它只有一半时间(我试过)

1 个答案:

答案 0 :(得分:1)

这会产生一个Nonce,但它不是一个加密的nonce。此库生成的值绝不能用于安全性,因为它严重依赖于时间的使用。攻击者知道当前时间,并且知道您的服务器时间,因为它在http响应头中。另外md5()的prng输出并不像应该的那样随机。针对md5存在许多已知漏洞,它应该永远不会用于安全性。另外10个字节的基数16相当小,16个字节的base256将是理想的。

如果您需要一个难以猜测的独特值,那么这在大多数情况下都适用:

sha1(uniqeid(mt_rand(),true));

然而,这并不理想。输出是base16,非常浪费空间。 uniqeid()仍然使用时间,但结果值中还有其他熵源。

到目前为止,Web应用程序的最佳熵源是/dev/urandom并使用fopen()来访问它并读出16个字节的base256内容。 / dev / urandom是一个熵存储,它从操作系统,其硬件和系统上所有应用程序的行为中收集随机源。