Jump to content

Recommended Posts

I wrote a Token Generator class based off the code from the following thread. It works as expected. I just want to get some more eyes on it for any feedback on improvements or problems.

 

http://forums.phpfreaks.com/topic/298729-forgotten-password/?hl=%2Bmcrypt_create_iv&do=findComment&comment=1524084

<?php

/**
 * Class Token
 *
 * Generates a Cryptographically Secure Pseudo Random Number Generator (CSPRNG)
 */

class Token
{
    /**
     * Generates a pseudo-random string of bytes
     *
     * @return string
     */
    public function getRandomBytes()
    {
        return openssl_random_pseudo_bytes(16);
    }

    /**
     * Convert (Encodes) binary data into hexadecimal representation
     *
     * Returns an ASCII string containing the hexadecimal representation of $randomBytes
     *
     * @param $randomBytes
     * @return string
     */
    public function getEncodedToken($randomBytes)
    {
        return bin2hex($randomBytes);
    }

    /**
     * Decodes a hexadecimally encoded binary string
     *
     * @param $encoded_token
     * @return string
     */
    public function getDecodedToken($encoded_token)
    {
        return hex2bin($encoded_token);
    }

    /**
     * Generate a hash value
     *
     * @param $raw_token
     * @return string
     */
    public function sha256Hash($raw_token)
    {
        return hash('sha256', $raw_token);
    }
}

//----------------------------------------------------------------------------
//Test
//----------------------------------------------------------------------------

$token = new Token();

/** Encode token and hash it */
$raw_token = $token->getRandomBytes();

echo $encoded_token =$token->getEncodedToken($raw_token);// Sent to User
echo '<br>';
echo $token_hash = $token->sha256Hash($raw_token);// Stored in DB
echo '<br>';


/** Decode token and hash it */
$raw_token = $token->getDecodedToken($encoded_token);
echo $token_hash = $token->sha256Hash($raw_token);// Compare user token to DB token

Link to post
Share on other sites

I would use random_bytes rather than openssl to generate your random byte data. Use the compatibility library if you need to.

 

sha256 hash is probably fine, but I tend to just re-use the same hashing code as for passwords, namely password_hash and password_verify.

 

I'd also consider altering the token class inteface. You're exposing things that I'd consider to be implementation details currently which could make things harder to change in the future.

 

class Token
{
    private $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public static function generate($length=16)
    {
        $raw = random_bytes($length);
        $token = bin2hex($raw);

        return new static($token);
    }

    public function getToken()
    {
        return $this->token;
    }

    public function getHash()
    {
        return password_hash($this->token, PASSWORD_DEFAULT);
    }

    public function matches($hash)
    {
        return password_verify($this->token, $hash);
    }
}


$token = Token::generate();
echo $token_plain = $token->getToken(); // Sent to User
echo '<br>';
echo $token_hash = $token->getHash(); //Stored in DB
echo '<br>';


/** Decode token and hash it */
$token = new Token($token_plain);
var_dump($token->matches($token_hash)); //Compare user token to DB token
I removed the encoding/decoding bit as I'm not sure if it's really necessary or not and it simplifies things. Hashing the bin2hex version instead means each byte has a limited value range, but you have twice as many bytes making up the hash.
Link to post
Share on other sites

I wouldn't even use a class for this. All the methods are wrappers around a single function call, and even with kicken's version it's a stretch to make this proper OOP. What's the point of having this live somewhere separate from its usage? If you need a token in a class or function or something then put the logic there.

 

Or another answer is,

 

PHP is naturally not object-oriented. Making functionality into a function is not a crime.

function sha256($str, $raw_output = false) {
	return hash("sha256", $str, $raw_output);
}
function token($length = 16) {
	return bin2hex(random_bytes($length));
}
  • Like 1
Link to post
Share on other sites
This thread is more than a year old.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.