Использование PBKDF2 в Java и переполнение стека

У меня возникли некоторые трудности при создании одного и того же зашифрованного пароля с использованием алгоритма PBKDF2 на Java и PHP.

Я использую следующую реализацию Java для генерации хеша со случайным байтовым массивом размером 16 байтов. Затем я храню хеш и соль отдельно в базе данных MySQL, однако, когда я собираюсь выполнить ту же операцию в PHP с использованием соли, извлеченной из базы данных, я получаю почти то же самое шифрование, за исключением того, что хеш имеет ведущий 0 и я не могу на всю жизнь сообразить почему.

Джава:

public String hashPassword(String password, byte[] salt){

char[] passwordChars = password.toCharArray();

PBEKeySpec spec = new PBEKeySpec(
passwordChars,
salt,
ITERATIONS,
KEY_LENGTH
);
SecretKeyFactory key = null;
try {
key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

byte[] hashedPassword = null;

try {
hashedPassword = key.generateSecret(spec).getEncoded();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return String.format("%x", new BigInteger(hashedPassword));

}

Я нашел выше код в https://adambard.com/blog/3-wrong-ways-to-store-a-password/

PHP:

$query = $database->query('SELECT * FROM USERS');

$password = 'hello';
$iterations = 1000;

foreach($query as $user){
$hash = hash_pbkdf2("sha1", $password, $user['salt'], $iterations, 40, false);

}
echo $hash;

Примечание: в базе данных хранится только один пользователь, я знаю, что приведенный выше код не очень хорош, я быстро его создал для целей тестирования.

Для обеих реализаций я использую счетчик итераций 1000, длину ключа 160 в Java и длину ключа 40 в PHP (чтобы компенсировать установку raw-output в false)

Java Output - 971f0dddc1bc2e899f2bca178f16ea79bfbbb13
PHP Output - 0971f0dddc1bc2e899f2bca178f16ea79bfbbb13

Любая помощь очень ценится, спасибо.

2

Решение

Это BigInteger это убивает ведущих 0.

Хэши не являются целыми числами, это массив 8-битных байтов. Не пытайтесь конвертировать в BigInteger,

Либо использовать его как byte[] или закодировать в виде шестнадцатеричной или Base64 строки. Чтобы соответствовать PHP шестнадцатеричное кодирование hashedPassword,

PHP возвращает хеш с шестнадцатеричной строкой, потому что raw_output установлен в FALSE,

4

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

Других решений пока нет …

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