Для приложения, над которым я работаю, nodejs должен проверять хэши, созданные PHP, и наоборот.
Проблема в том, что хэши, сгенерированные в PHP (через Laravel’s Hash
класс, который просто использует PHP password_hash
функция) возвращает false при тестировании в node.js.
Следующий скрипт node.js:
var bcrypt = require('bcrypt');
var password = 'password';
var phpGeneratedHash = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
var nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
console.log(
bcrypt.compareSync(password, phpGeneratedHash) ? 'PHP passed' : 'PHP failed',
bcrypt.compareSync(password, nodeGeneratedHash) ? 'nodejs passed' : 'nodejs failed'
);
выводит: «PHP fail nodejs пройден», тогда как следующий скрипт PHP:
<?php
$password = 'password';
$phpGeneratedHash = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
print password_verify($password, $phpGeneratedHash) ? 'PHP passed' : 'PHP failed';
print password_verify($password, $nodeGeneratedHash) ? 'nodejs passed' : 'nodejs failed';
выводит «PHP прошел nodejs пройден».
Я запустил тесты в Ubuntu 14.04.1 с использованием PHP 5.5.18, node.js v0.10.32 и модуля npm bcrypt.
Это терпит неудачу, потому что типы хэшей bcrypt, генерируемых из php и узла, отличаются. Laravel генерирует $2y$
в то время как узел генерирует $2a$
, Но хорошая новость — единственная разница между 2a
а также 2y
их префиксы.
Поэтому вы можете сделать один из префиксов похожим на другой. Подобно:
$phpGeneratedHash = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
Для чего-то вроде:
$phpGeneratedHash = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2y$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';
Обратите внимание, что я заменил $2a$
хеш-узла $2y$
, Вы можете просто сделать это с:
$finalNodeGeneratedHash = str_replace("$2a$", "$2y$", $nodeGeneratedHash);
finalNodeGeneratedHash = nodeGeneratedHash.replace('$2a$', '$2y$');
Тогда сравните phpGeneratedHash
в finalNodeGeneratedHash
,
Примечание: если вы сравниваете в PHP, рекомендуется изменить префикс сгенерированного хеша NodeJS на
$2y$
и если вы сравниваете в NodeJS; изменить префикс сгенерированного PHP хеша на$2a$
,
Я пытался вычислить то, что было сказано раньше, чтобы получить коды, которые работают. Как видите, мне не нужно ничего заменять.
На стороне PHP 7.2.4:
<?php
$password = "test123";
$hash = password_hash($password, PASSWORD_BCRYPT);
echo $hash; // I get $2y$10$5EaF4lMSCFWe7YqqxyBnR.QmDu1XhoiaQxrOFw.AJZkGCYmpsWDU6
На стороне узла JS:
Установить пакет bcryptjs: npm и bcryptjs
var bcrypt = require('bcryptjs');
let hash1="$2y$10$5EaF4lMSCFWe7YqqxyBnR.QmDu1XhoiaQxrOFw.AJZkGCYmpsWDU6";
console.log(bcrypt.compareSync("test123", hash1)); // display true