Проблема аутентификации пароля SHA512, зашифрованного из .NET в PHP

Я уже некоторое время пытаюсь аутентифицировать пароль, зашифрованный в .NET, из PHP API, и, несмотря на то, что я пробовал разные способы, я не могу заставить его соответствовать.

Пароль был зашифрован с помощью SHA512 и сохранен в базе данных в двоичном (64) поле с использованием этой точной функции (которую я не могу контролировать, ее нельзя изменить. соль не используется):

> public byte[] GetHashablePw(string pwByte)
>     {
>         System.Security.Cryptography.SHA512Managed sm = new System.Security.Cryptography.SHA512Managed();
>         System.Text.UnicodeEncoding u = new System.Text.UnicodeEncoding();
>         byte[] b = new byte[-1 + 1];
>         b = sm.ComputeHash(u.GetBytes(pwByte));
>         return b;
>     }

Когда я хочу сравнить пароль, который предоставляет пользователь, я пробовал разные способы:

    $pwhash = openssl_digest($_POST['pw'], 'sha512');
    $pwhash = bin2hex(pack('H*', hash('SHA512',$_POST['pw'])));
    $pwhash = openssl_digest(utf8_decode($_POST['pw']), 'sha512');
    $pwhash = bin2hex(hash('sha512', $_POST['pw'], true));

которые на самом деле возвращают один и тот же результат, но ни один из них не соответствует тому, что было сохранено в базе данных из .NET.

Я получаю свой хэш пароля, хранящийся в базе данных, следующим образом:

bin2hex($pwFromDB);

В одном конкретном случае я получаю это как хэш, хранящийся в базе данных:

4c0dc75a062dd4957f6f91350f6d3f54f910989e6ffe82749cdc580b9eae5dce0ee743cd513d005d0c399e23b0190809767fe1a57f9fecbce0a928296181c14e

в то время как я получаю это от функций PHP, используя тот же пароль:

c3cf6055cbb36e3eace5ca470922de6e754ec93cf80f35459c910f4381899483e2c29565f062476724dad94929527d53eeae5a1cd708c6227574e58748d354aa

Буду признателен за любую помощь в понимании того, что мне не хватает.


person user3242224    schedule 01.08.2018    source источник
comment
Имейте в виду, что алгоритмы быстрого хэширования, такие как SHA-*, не подходят для хеширования паролей, вместо этого используйте функцию хеширования паролей с коэффициентом стоимости, например BCrypt, SCrypt, Argon2 или PBKDF2.   -  person martinstoeckli    schedule 02.08.2018
comment
@martinstoeckli В этом случае я не могу контролировать часть .NET, поэтому я не могу решить. В моих обычных проектах я использую password_hash и password_verify, используя PASSWORD_DEFAULT. Это нормально, верно?   -  person user3242224    schedule 03.08.2018
comment
Это рекомендуемый способ, да. И если вам нужна совместимость между DotNet и PHP, вы можете использовать совместно библиотеку dotnet BCrypt. с PASSWORD_BCRYPT.   -  person martinstoeckli    schedule 03.08.2018


Ответы (1)


С# использует UnicodeEncoding, то есть UTF-16LE.

Вам нужно получить данные PHP в том же представлении, поскольку криптография работает с байтами, а не с текстом. http://php.net/manual/en/function.mb-convert-encoding.php может быть тем, что вам нужно.


Кроме того, строка не зашифрована. Шифрование требует операции отмены (дешифрования). То, что было сделано здесь, это хеширование. Этот пароль был хеширован.

person bartonjs    schedule 01.08.2018
comment
Спасибо, это сработало отлично! Я думал, что UnicodeEncoding — это ISO-8859-1, поэтому я попытался использовать utf8_decode. - person user3242224; 01.08.2018