CPasswordHelper
| Пакет | system.utils |
|---|---|
| Наследование | class CPasswordHelper |
| С момента | 1.1.14 |
| Исходный код | framework/utils/CPasswordHelper.php |
CPasswordHelper использует алгоритм хеширования Blowfish, доступный во многих средах выполнения PHP через встроенную функцию PHP crypt(). По состоянию на декабрь 2012 года это самый надёжный доступный в PHP алгоритм, и единственный без проблем безопасности. По этой причине, CPasswordHelper не работает в среде, где функция crypt() не поддерживает вариант Blowfish и исправление хеша $2y. Совместимые системы:
(1) Большинство *nix-систем с PHP 4 (алгоритм является частью библиотечной функции crypt(3)); (2) Любой PHP с версии 5.3.7 или PHP с патчем Suhosin, включающим исправление $2y. Обратите внимание, что Debian 5.3.3 не поддерживается.
Для получения дополнительной информации о хешировании паролей, функции crypt() и алгоритме Blowfish, пожалуйста, прочитайте статью в вики Yii Использование crypt() для хранения паролей и RFC PHP Добавление простого API для хеширования паролей.
CPasswordHelper вызывает исключение, если алгоритм Blowfish недоступен в функции crypt() PHP в среде выполнения. Он может быть использован следующим образом
Генерация хеша из пароля:
$hash = CPasswordHelper::hashPassword($password);Этот хеш может быть сохранён в базе данных (например, CHAR(60) CHARACTER SET latin1). Хеш обычно генерируется и сохраняется в базе данных, когда пользователь вводит новый пароль. Но он также может быть полезен для генерации и сохранения хеша после проверки пароля пользователя, чтобы изменить затраты или обновить соль.
Для проверки пароля, извлеките сохранённый хеш пользователя из базы данных (в $hash) и:
if (CPasswordHelper::verifyPassword($password, $hash))
// password is good
else
// password is bad
Общедоступные методы
| Метод | Описание | Определено |
|---|---|---|
| generateSalt() | Генерирует соль, которую можно использовать для генерации хеша пароля. | CPasswordHelper |
| hashPassword() | Генерирует безопасный хеш из пароля и случайной соли. | CPasswordHelper |
| same() | Проверяет совпадение двух строк, используя алгоритм с независимым от времени выполнением | CPasswordHelper |
| verifyPassword() | Проверяет пароль по хешу. | CPasswordHelper |
Защищённые методы
| Метод | Описание | Определено |
|---|---|---|
| checkBlowfish() | Проверка наличия PHP crypt() с опцией хеширования Blowfish. | CPasswordHelper |
Подробные описания методов
checkBlowfish() метод
protected static void checkBlowfish() |
protected static function checkBlowfish()
{
if(!function_exists('crypt'))
throw new CException(Yii::t('yii','{class} requires the PHP crypt() function. This system does not have it.',
array('{class}'=>__CLASS__)));
if(!defined('CRYPT_BLOWFISH') || !CRYPT_BLOWFISH)
throw new CException(Yii::t('yii',
'{class} requires the Blowfish option of the PHP crypt() function. This system does not have it.',
array('{class}'=>__CLASS__)));
}
Проверка наличия PHP crypt() с опцией хеширования Blowfish.
generateSalt() метод
public static string generateSalt(int $cost=13) | ||
| $cost | int | Параметр затрат, используемый алгоритмом хеширования Blowfish. |
| {return} | string | значение случайной соли. |
public static function generateSalt($cost=13)
{
if(!is_numeric($cost))
throw new CException(Yii::t('yii','{class}::$cost must be a number.',array('{class}'=>__CLASS__)));
$cost=(int)$cost;
if($cost<4 || $cost>31)
throw new CException(Yii::t('yii','{class}::$cost must be between 4 and 31.',array('{class}'=>__CLASS__)));
if(($random=Yii::app()->getSecurityManager()->generateRandomString(22,true))===false)
if(($random=Yii::app()->getSecurityManager()->generateRandomString(22,false))===false)
throw new CException(Yii::t('yii','Unable to generate random string.'));
return sprintf('$2y$%02d$',$cost).strtr($random,array('_'=>'.','~'=>'/'));
}
Генерирует соль, которую можно использовать для генерации хеша пароля.
Встроенная функция PHP crypt() для алгоритма хеширования Blowfish требует строку соли в определённом формате: "$2y$" (где "y" может быть заменено на "a" или "y", см. руководство PHP для подробностей), двухзначный параметр затрат, "$", 22 символа из алфавита "./0-9A-Za-z".
hashPassword() метод
public static string hashPassword(string $password, int $cost=13) | ||
| $password | string | Пароль для хеширования. |
| $cost | int | Параметр затрат, используемый алгоритмом хеширования Blowfish. Чем выше значение затрат, тем дольше потребуется для генерации хеша и проверки пароля по нему. Более высокие затраты замедляют атаку методом грубой силы. Для лучшей защиты от атак методом грубой силы установите его на максимально возможное значение для серверов в режиме эксплуатации. Время вычисления хеша удваивается при каждом увеличении $cost на единицу. Например, если вычисление хеша занимает 1 секунду при $cost = 14, то время вычисления изменяется как 2^($cost - 14) секунды. |
| {return} | string | Строка хеша пароля, всегда 60 символов ASCII. |
public static function hashPassword($password,$cost=13)
{
self::checkBlowfish();
$salt=self::generateSalt($cost);
$hash=crypt($password,$salt);
if(!is_string($hash) || (function_exists('mb_strlen') ? mb_strlen($hash, '8bit') : strlen($hash))<32)
throw new CException(Yii::t('yii','Internal error while generating hash.'));
return $hash;
}
Генерирует безопасный хеш из пароля и случайной соли.
Использует встроенную функцию PHP crypt() с опцией хеширования Blowfish.
same() метод
public static bool same(string $a, string $b) | ||
| $a | string | Первая строка для сравнения. |
| $b | string | Вторая строка для сравнения. |
| {return} | bool | true, если строки совпадают; false, если они отличаются или если ни одна из них не является строкой. |
public static function same($a,$b)
{
if(!is_string($a) || !is_string($b))
return false;
$mb=function_exists('mb_strlen');
$length=$mb ? mb_strlen($a,'8bit') : strlen($a);
if($length!==($mb ? mb_strlen($b,'8bit') : strlen($b)))
return false;
$check=0;
for($i=0;$i<$length;$i+=1)
$check|=(ord($a[$i])^ord($b[$i]));
return $check===0;
}
Проверка совпадения двух строк с алгоритмом, не зависящим от времени выполнения, если строки имеют одинаковую длину.
Функция может быть полезна для предотвращения атак с использованием времени выполнения. Например, если $a и $b являются значениями хеша из одного и того же алгоритма, то время выполнения этой функции не выдает информацию о наличии совпадения.
ПРИМЕЧАНИЕ: время выполнения зависит, если $a и $b имеют разную длину, или ни одна из них не является строкой. В целях проверки хеша пароля это не раскрывает информацию, полезную для злоумышленника.
См. также
verifyPassword() метод
public static bool verifyPassword(string $password, string $hash) | ||
| $password | string | Пароль для проверки. Если пароль пуст или не является строкой, метод вернёт false. |
| $hash | string | Хеш для проверки пароля. |
| {return} | bool | True, если пароль соответствует хешу. |
public static function verifyPassword($password, $hash)
{
self::checkBlowfish();
if(!is_string($password) || $password==='')
return false;
if (!$password || !preg_match('{^\$2[axy]\$(\d\d)\$[\./0-9A-Za-z]{22}}',$hash,$matches) ||
$matches[1]<4 || $matches[1]>31)
return false;
$test=crypt($password,$hash);
if(!is_string($test) || strlen($test)<32)
return false;
return self::same($test, $hash);
}
Проверка пароля по хешу.
© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc/api/1.1/CPasswordHelper