简体   繁体   中英

How can I improve this NONCE library for PHP?

This is the first time I've worked with nonces, so I downloaded the script from http://fullthrottledevelopment.com/php-nonce-library . I did not like the code, especially because there's a chance of a legitimate request being treated as invalid because the function works in intervals of a defined amount of time (default is 300 seconds).

For example, we could be 299 seconds into the 300 seconds when the nonce is generated, so the nonce would only work for 1 second.

I modified the library into the following functions. What I did was check for the current interval and the previous interval by using nonce_create(time()-NONCE_DURATION)==$nonce . Are there ways to further improve the functions?:

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;
}

Also, I have two questions regarding the original library:

  1. Why isn't NONCE_UNIQUE_KEY used? Did the author simply forget?
  2. Why does the author divide by two here: $i = ceil( time() / ( FT_NONCE_DURATION / 2 ) ); , it only works for half the time then (I tried it)

This produces a Nonce, however it is not a cryptographic nonce. The value that this library produces must never be used for security because it is heavily dependent on the use of time. The attacker knows the current time, and knows your server time because its in the http response header. Also md5()'s prng output isn't as random as it should be. There are many known vulnerabilities against md5, and it should never be used for security. Also 10 bytes of base 16 pretty small, 16 bytes of base256 would be ideal.

If you need a unique value that is reasonably hard to guess then this will work in most cases:

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

However, this is less than ideal. the output is base16 which is very wasteful of space. uniqeid() still uses time, however there are other sources of entropy in the resulting value.

By far the best source of entropy for a web application is /dev/urandom and use fopen() to access it and read out 16 bytes of the base256 contents. /dev/urandom is an entropy store that gathers sources of randomness from the operation system, its hardware, and the behavior of all applications on the system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM