Выход crypt
состоит из:
- (опционально идентификатор алгоритма + коэффициент загрузки)
- соль по используемому алгоритму
- настоящий хэш
Когда вы передадите этот вывод "соль" обратно в crypt
, он извлечет правильный алгоритм и соль и использует их для операции. Если упоминается только алгоритм, он использует его и генерирует случайную соль. В противном случае он выберет алгоритм по умолчанию и сгенерирует случайную соль. Часть hash
в переданном параметре соли игнорируется.
Таким образом, вы можете просто сравнить свой сохраненный_хэш с криптой (пароль, сохраненный_хэш) - если он равен, вполне вероятно, что это был правильный пароль.
Вот объяснение псевдокода (в PHP-подобном синтаксисе), как работает crypt:
function crypt($password, $salt)
{
if (substr($salt,0 1) == "_") {
$count = substr($salt, 1, 4);
$real_salt = substr($salt, 5, 4);
return "_" . $count . $real_salt . crypt_ext_des($password, $count, $salt);
}
if(substr($salt, 0, 3) == "$1$") {
list($ignored, $real_salt, $ignored) = explode("$", $salt);
return "$1$" . $real_salt . "$" . crypt_md5($password, $real_salt);
}
if(substr($salt, 0, 4) == "$2a$") {
$cost = substr($salt, 4, 2);
$real_salt = substr($salt, 7, 22);
return "$2a$" . $cost . "$" . $real_salt . crypt_brypt($password, $real_salt, $cost);
}
// ... SHA256 and SHA512 analogons
// no match => STD_DES
$real_salt = substr($salt, 0, 2);
return $real_salt . crypt_std_des($password, $real_salt);
}
Затем отдельные функции crypt_xxx выполняют реальную работу, в зависимости от алгоритма.
(На самом деле, генерация случайной соли в этом описании отсутствует. Это будет сделано, если $ real_salt пуст.)