From b318b8ee9cecbf9c21e3e379743488e2c53f2584 Mon Sep 17 00:00:00 2001 From: Korvin Szanto Date: Thu, 1 Dec 2016 11:22:51 -0800 Subject: [PATCH] Generate secure random strings from the identifier service Former-commit-id: dc5cd61fc7474a87c62d1da87adb6919caf444c5 Former-commit-id: 5a78c155360aff77f0b0976ca4e7d68d7493a145 --- .../src/Utility/Service/Identifier.php | 133 ++++++++++-------- 1 file changed, 78 insertions(+), 55 deletions(-) diff --git a/web/concrete/src/Utility/Service/Identifier.php b/web/concrete/src/Utility/Service/Identifier.php index e639b11f8d2..a5e8620f631 100644 --- a/web/concrete/src/Utility/Service/Identifier.php +++ b/web/concrete/src/Utility/Service/Identifier.php @@ -1,9 +1,14 @@ * @copyright Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org) * @license http://www.concrete5.org/license/ MIT License @@ -11,76 +16,94 @@ /** * A helper that allows the creation of unique strings, for use when creating hashes, identifiers. - * @package Helpers + * + * \@package Helpers * @subpackage Validation + * * @author Andrew Embler * @copyright Copyright (c) 2003-2008 Concrete5. (http://www.concrete5.org) * @license http://www.concrete5.org/license/ MIT License */ +class Identifier +{ -class Identifier { - - private $letters = 'abcefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; - - - /** - * Like generate() below, but simply appends an ever increasing number to what you provide - * until it comes back as not found - */ - public function generateFromBase($string, $table, $key) { - $foundRecord = false; - $db = Loader::db(); - $i = ''; + /** + * Like generate() below, but simply appends an ever increasing number to what you provide + * until it comes back as not found. + */ + public function generateFromBase($string, $table, $key) + { + $foundRecord = false; + $db = Application::make(Connection::class); + $i = ''; $_string = ''; - while ($foundRecord == false) { - $_string = $string . $i; - $cnt = $db->GetOne("select count(" . $key . ") as total from " . $table . " where " . $key . " = ?", array($_string)); - if ($cnt < 1) { - $foundRecord = true; - } else { - if ($i == '') { - $i = 0; - } - $i++; - } - } - return $_string; - } + while ($foundRecord == false) { + $_string = $string . $i; + $cnt = $db->GetOne("select count(" . $key . ") as total from " . $table . " where " . $key . " = ?", + array($_string)); + if ($cnt < 1) { + $foundRecord = true; + } else { + if ($i == '') { + $i = 0; + } + ++$i; + } + } + + return $_string; + } /** * Generates a unique identifier for an item in a database table. Used, among other places, in generating - * User hashes for email validation + * User hashes for email validation. + * * @param string $table * @param string $key * @param int $length * @param bool $lowercase + * * @return string */ - public function generate($table, $key, $length = 12, $lowercase = false) { - $foundHash = false; - $db = Loader::db(); - while ($foundHash == false) { - $string = $this->getString($length); - if ($lowercase) { - $string = strtolower($string); - } - $cnt = $db->GetOne("select count(" . $key . ") as total from " . $table . " where " . $key . " = ?", array($string)); - if ($cnt < 1) { - $foundHash = true; - } - } - return $string; - } + public function generate($table, $key, $length = 12, $lowercase = false) + { + $foundHash = false; + $db = Application::make(Connection::class); + while ($foundHash == false) { + $string = $this->getString($length); + if ($lowercase) { + $string = strtolower($string); + } + $cnt = $db->GetOne("select count(" . $key . ") as total from " . $table . " where " . $key . " = ?", + array($string)); + if ($cnt < 1) { + $foundHash = true; + } + } + + return $string; + } - public function getString($length = 12) { - $str = str_repeat($this->letters, 10); - $hash = substr(str_shuffle($str), 0, $length); - return $hash; - } + /** + * Generate a cryptographically secure random string + * @param int $length + * @return string + */ + public function getString($length = 12) + { + if (function_exists('random_bytes')) { + $bytes = random_bytes($length / 2); + } else { + $hash = new PasswordHash(8, false); + $bytes = $hash->get_random_bytes($length / 2); + } - public function deleteKey($table, $keyCol, $uHash){ - $db = Loader::db(); - $db->Execute("DELETE FROM ".$table." WHERE ".$keyCol."=?", array($uHash) ); - } + return bin2hex($bytes); + } + public function deleteKey($table, $keyCol, $uHash) + { + $db = Application::make(Connection::class); + $db->Execute("DELETE FROM " . $table . " WHERE " . $keyCol . "=?", array($uHash)); + } }