Метод verify используется для проверки соответствия пароля заранее сформированному хешу. Его задача — определить, совпадает ли введённая строка с исходным паролем, который был преобразован в криптографический хеш с учётом соли и параметров алгоритма.
Основная идея заключается в том, что исходный пароль никогда не извлекается из хеша. Вместо этого выполняется повторное хеширование входного значения с теми же параметрами, после чего результаты сравниваются.
При вызове проверки происходит следующая последовательность действий:
Ключевой момент заключается в том, что сравнение должно быть устойчивым к атакам по времени выполнения (timing attacks). Поэтому библиотеки, реализующие password-hash, используют безопасные механизмы сравнения.
Хеш, с которым работает метод verify, обычно представляет собой строку, содержащую все необходимые параметры для проверки:
Пример условного формата:
algorithm:iterations:salt:hash
или более абстрактный вариант:
pbkdf2$10000$randomSalt$generatedHash
Метод verify не требует передачи параметров отдельно — они уже встроены в строку хеша.
Логика метода verify в библиотеке password-hash можно представить следующим образом:
Псевдокод:
function verify(password, storedHash) {
const parsed = parseHash(storedHash);
const computedHash = hashPassword(
password,
parsed.algorithm,
parsed.salt,
parsed.iterations
);
return safeCompare(computedHash, parsed.hash);
}
Функция safeCompare критически важна, так как обычное
сравнение строк может раскрывать информацию через различие во времени
выполнения.
В реальной среде Node.js метод verify используется крайне просто:
const passwordHash = require('password-hash');
const hash = passwordHash.generate('securePassword123');
const result1 = passwordHash.verify('securePassword123', hash);
const result2 = passwordHash.verify('wrongPassword', hash);
console.log(result1); // true
console.log(result2); // false
В данном примере:
true, так как пароль
совпадает;false, так как строка не
соответствует исходному значению.Метод verify скрывает внутри себя несколько важных механизмов:
Если хеш был создан с использованием разных параметров, verify автоматически подбирает нужный алгоритм на основе метаданных внутри строки.
Соль не передаётся отдельно, она извлекается из хеша. Это исключает необходимость хранения дополнительных данных.
Каждый вызов verify выполняет полноценное хеширование, что делает массовый перебор вычислительно дорогим процессом.
Одна из распространённых ошибок — попытка сравнить хеши напрямую:
if (hash === passwordHash.generate(input)) {
// некорректный подход
}
Такой подход ломает безопасность и может приводить к неправильным результатам из-за различий в соли и параметрах.
Иногда хеш ошибочно передаётся в verify как пароль:
passwordHash.verify(hash, hash);
В этом случае сравнение теряет смысл, так как входное значение уже не является исходным паролем.
Ручное изменение строки хеша (например, обрезка или конкатенация) делает проверку невозможной, поскольку нарушается структура данных.
Если пароль не совпадает с хешем, метод verify возвращает строгое
логическое значение false. Ошибки при этом не
выбрасываются, поскольку несовпадение не считается исключительной
ситуацией.
Однако возможны случаи, когда:
В таких ситуациях поведение зависит от реализации библиотеки, но чаще
всего также возвращается false.
Ключевой аспект работы verify — защита от timing attack. При обычном сравнении строк разница во времени обработки может раскрыть информацию о совпадающих префиксах.
Безопасное сравнение реализуется так, чтобы время выполнения зависело только от длины строки, а не от её содержимого.
Пример принципа безопасного сравнения:
function safeCompare(a, b) {
if (a.length !== b.length) return false;
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
}
return result === 0;
}
В системах аутентификации verify выполняет центральную функцию проверки личности пользователя без хранения пароля в открытом виде. В связке с генерацией хеша он образует полный цикл:
Такой подход исключает необходимость обратного восстановления пароля и снижает риск компрометации данных даже при утечке базы.