benanamen Posted April 22, 2018 Share Posted April 22, 2018 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 Quote Link to comment Share on other sites More sharing options...
kicken Posted April 22, 2018 Share Posted April 22, 2018 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. Quote Link to comment Share on other sites More sharing options...
requinix Posted April 23, 2018 Share Posted April 23, 2018 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)); } 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.