diff --git a/app/classes/Framadate/Security/Token.php b/app/classes/Framadate/Security/Token.php index 7222dbf..b4a4b9b 100644 --- a/app/classes/Framadate/Security/Token.php +++ b/app/classes/Framadate/Security/Token.php @@ -5,14 +5,17 @@ class Token { private $time; private $value; + private $length; + private static $codeAlphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'; - function __construct() { + function __construct($length = 64) { + $this->length = $length; $this->time = time() + TOKEN_TIME; $this->value = $this->generate(); } private function generate() { - return sha1(uniqid(mt_rand(), true)); + return self::getToken($this->length); } public function getTime() { @@ -31,5 +34,58 @@ class Token { return $value === $this->value; } + /** + * Get a secure token if possible, or a less secure one if not. + * + * @param int $length The token length + * @param bool $crypto_strong If passed, tells if the token is "cryptographically strong" or not. + * @return string + */ + public static function getToken($length, &$crypto_strong = false) { + if (function_exists('openssl_random_pseudo_bytes')) { + openssl_random_pseudo_bytes(1, $crypto_strong); // Fake use to see if the algorithm used was "cryptographically strong" + return self::getSecureToken($length); + } + return self::getUnsecureToken($length); + } + + public static function getUnsecureToken($length) { + $string = ''; + mt_srand(); + for ($i = 0; $i < $length; $i++) { + $string .= self::$codeAlphabet[mt_rand() % strlen(self::$codeAlphabet)]; + } + + return $string; + } + + /** + * @author http://stackoverflow.com/a/13733588 + */ + public static function getSecureToken($length){ + $token = ""; + for($i=0;$i<$length;$i++){ + $token .= self::$codeAlphabet[self::crypto_rand_secure(0,strlen(self::$codeAlphabet))]; + } + return $token; + } + + /** + * @author http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322 + */ + private static function crypto_rand_secure($min, $max) { + $range = $max - $min; + if ($range < 0) return $min; // not so random... + $log = log($range, 2); + $bytes = (int) ($log / 8) + 1; // length in bytes + $bits = (int) $log + 1; // length in bits + $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 + do { + $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); + $rnd = $rnd & $filter; // discard irrelevant bits + } while ($rnd >= $range); + return $min + $rnd; + } + } \ No newline at end of file