Как проверить сгенерированный java пароль ha sh (sha-256) в nodejs? - PullRequest
1 голос
/ 11 июля 2020

Я работаю в устаревшем решении со службой java, которая управляет регистрацией пользователей. Для каждого пользователя сервис java генерирует пароль ha sh, который сохраняется в нашей БД вместе с использованной солью. Код java использует метод org.apache.shiro.crypto.hash.Sha256Hash для генерации ha sh.

Теперь я пытаюсь проверить того же пользователя в службе Nodejs, взяв ту же соль, с которой я Я хеширую новый пароль, введенный пользователем, и сравниваю его с паролем того же пользователя ha sh из БД. Однако я не могу заставить его соответствовать, и я не знаю, почему / где это идет не так.

Java фрагмент кода, который используется для хеширования

public static final int HASH_ITERATIONS = 1004;
public static final String HASH_ALGORITHM = Sha256Hash.SHA-256;
hashedPw = new Sha256Hash(password, new SimpleByteSource(salt), HASH_ITERATIONS).toHex();
// hashedPW and salt are stored in DB

Моя ошибка Nodejs попытка:

// Getting salt and hashedPw from DB, they are
// salt = <Buffer 1e e7 1d 5a ec f2 a1 02 e9 9c 86 d7 33 04 a4 5b>
// hashedPw = f88b92d40fbc1644395d704d4f29d7e702fc8add275d5e93a52a3645611fd352

// Using crypto library, assuming length of salt is 16 bytes (given trace above)
// and that the hash algorithm corresponding to SHA-256 is 'sha256' in nodejs-crypto
const key = crypto.pbkdf2Sync(password, salt, 1004, 16, 'sha256');
console.log(key);
console.log(key.toString('hex'));

//This prints:
// <Buffer 80 10 b5 30 0e ca e0 ff 1f 97 96 1b b4 d4 d3 41>
// 8010b5300ecae0ff1f97961bb4d4d341
// which clearly doesn't match the 'hashedPw' above

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

** Изменить (Дополнительно информация, запрашиваемая в комментарии) **

(я создал нового временного пользователя, чтобы иметь возможность делиться всей информацией) Хешированный пароль: myTest123

Соль, которая используется в коде java: NJxGXOhrAWJ1pPNm2Hg29Q==

Полученный хешированный пароль: 63816c31d2221151edf8134de7d9b2fb4d2d189ce5fc1084b84b33c28441217c

Результат, который я получаю из pbkdf2Syn c (на nodejs журнал консоли выше):

<Buffer d4 9b 98 09 aa a1 92 c9 ca 70 0a 34 5b ca cb 13>
d49b9809aaa192c9ca700a345bcacb13

1 Ответ

1 голос
/ 12 июля 2020

Как @ x4rf41 предположил прямо в его комментарии, PBKDF2 не должен использоваться, вместо этого ha sh, сгенерированный SHA256, должен быть снова хеширован с помощью SHA256 каждый раз в соответствии с количеством итераций, см. SimpleHash#hash. Поэтому возможная реализация NodeJS (с использованием ваших тестовых данных):

const crypto = require("crypto");

// Set salt, password and iteration count
const salt = Buffer.from('NJxGXOhrAWJ1pPNm2Hg29Q==', 'base64');
const password = 'myTest123';
const hashIterations = 1004;

// Iteration 0
var value = crypto.createHash('sha256').update(salt).update(password).digest();

// Iterations 1 to hashIterations - 1
var hashIteration = 1;
while (hashIteration++ < hashIterations) {
    value = crypto.createHash('sha256').update(value).digest();
}
console.log(value.toString('hex')); // 63816c31d2221151edf8134de7d9b2fb4d2d189ce5fc1084b84b33c28441217c

NodeJS не реализует функцию reset для класса Hash (как это было сделано в Java с MessageDigest#reset, который также применяется org.apache.shiro.crypto.hash.Sha256Hash), т.е. после вызова digest() объект Hash больше не может использоваться, поэтому его необходимо воссоздать .

Обратите внимание, что NJxGXOhrAWJ1pPNm2Hg29Q== - это не соль, а соль в кодировке Base64.

...