node.js — Сравнение хэша BCrypt между PHP и NodeJS

Для приложения, над которым я работаю, 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.

19

Решение

Это терпит неудачу, потому что типы хэшей 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$, Вы можете просто сделать это с:

PHP

$finalNodeGeneratedHash = str_replace("$2a$", "$2y$", $nodeGeneratedHash);

Узел

finalNodeGeneratedHash = nodeGeneratedHash.replace('$2a$', '$2y$');

Тогда сравните phpGeneratedHash в finalNodeGeneratedHash,

Примечание: если вы сравниваете в PHP, рекомендуется изменить префикс сгенерированного хеша NodeJS на $2y$ и если вы сравниваете в NodeJS; изменить префикс сгенерированного PHP хеша на $2a$,

51

Другие решения

Я пытался вычислить то, что было сказано раньше, чтобы получить коды, которые работают. Как видите, мне не нужно ничего заменять.

На стороне 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
2

По вопросам рекламы [email protected]