PDA

Просмотр полной версии : [Вопрос] SHA256_PassHash



Geebrox
22.01.2017, 22:15
При проверке пароля, функция SHA256_PassHash хеширует пароль по другому. То есть передается тот же соль и тот же пароль, но значение разное.

Код:


bool:CheckPassword(password[], expected_hash[], salt[])
{ // by Daniel_Cortez
new hash[64 + 1];
SHA256_PassHash(password, salt, hash, sizeof(hash));
printf("\n\n%s\n\n%s", hash, expected_hash);
printf("\n\n%d | %d\n\n", strlen(hash), strlen(expected_hash));
printf("\n\n%s\n\n%s", salt, player[0][player_salt]);
printf("\n\n%d | %d\n\n", strlen(salt), strlen(player[0][player_salt]));
return bool:(strcmp(hash, expected_hash) == 0);
} // использую нулевой ид игрока, так как на сервере только я (под 0 ид)

Логи:



6C3C8C95ED0577458DF28209AED66F73021F11D95FBB0083CC45CD3068743D81 // хешированный пароль, которого игрок ввел

AEF3BA85A58F8C10EE577E5C57C8FB03F996FE2C15FA1D37FEE37E70F882416F // хешированный пароль из бд

64 | 64 // длина строк



GrjxgKGYG28tvpmhRiWklZyE2QIxQ5PWTnTPpQyBg4IwW35imEQzPQbPjtRUtgdU // соль

GrjxgKGYG28tvpmhRiWklZyE2QIxQ5PWTnTPpQyBg4IwW35imEQzPQbPjtRUtgdU // соль

64 | 64 // длина строк

$continue$
22.01.2017, 22:30
А ты уверен, что игрок с первого раза ввел свой пароль?

Geebrox
22.01.2017, 22:35
А ты уверен, что игрок с первого раза ввел свой пароль?

Сам как думаешь? Я выше написал, что на сервере ТОЛЬКО Я (под 0 ид) и я разве могу ошибиться со своим паролем, или открыл бы эту тему не проверяя этот аргумент? Я уверен, что ввожу один и тот же пароль, даже создал 2 акка для проверки.

DeimoS
22.01.2017, 22:52
Значит либо при регистрации пароль хэшируешь неправильно, либо проверяешь неверно. Функция работает нормально.
Возьми свой пароль, соль и захэшируй их в OnGameModeInit с выводом в консоль, а после посмотри с каким из двух результатов будет совпадать

Geebrox
22.01.2017, 23:12
Значит либо при регистрации пароль хэшируешь неправильно, либо проверяешь неверно. Функция работает нормально.
Возьми свой пароль, соль и захэшируй их в OnGameModeInit с выводом в консоль, а после посмотри с каким из двух результатов будет совпадать

результат не совпадает с хешом из бд, значит проблема при создание хеша во время регистрации. Но я не нашел никаких проблем там.
Функция создание хеша при регистрации:


stock CreatePlayerPassword(playerid, password[])
{
player[playerid][player_salt][0] = EOS;
player[playerid][player_password][0] = EOS;
new length = strlen(random_letters);
for(new i = 0; i < 65; i++)
{
player[playerid][player_salt][i] =
random_letters[random(length)];
}
SHA256_PassHash(password, player[playerid][player_salt],
player[playerid][player_password], 65);
return 1;
}

DeimoS
23.01.2017, 00:12
Ну логируй то, какие данные приходят в функцию до хэширования, какая получается соль и какой результат. А после смотри что попадает в БД.

Причина, скорее всего, в коде, который вызывает показанные тобой функции, а не в самих функциях

Geebrox
23.01.2017, 19:22
Причина, скорее всего, в коде, который вызывает показанные тобой функции, а не в самих функциях

Причина оказалось в самой функции CreatePlayerPassword, точно не знаю почему pawn так повел себя (очень странно). Короче говоря, перенес весь код (т.е. цикл с созданием соля) в OnGameModeInit и логировал длину получаемого соля (создавал массив с 65 ячейками для соля, так же как и в энуменаторе игрока), длина строки оказалась 67. Не знаю как так получалось. Изменил кол-во циклов с 65 на 64, длина строки изменилась на 64 (т.е. на нормальную длину, которая должна была быть). Ну вкратце, проблема решена, но тему оставлю открытой, вдруг кто знает в чем именно заключалась моя ошибка и почему длина строки получалась в 67 символов, хотя я компилировал дебаг режимом (-d3) и с подключенным crashdetect'ом.

P.S. Крашев не было (т.е. связанных с выходом за пределы массива). Crashdetect молчал.

qwezert
23.01.2017, 19:25
Причина оказалось в самой функции CreatePlayerPassword, точно не знаю почему pawn так повел себя (очень странно). Короче говоря, перенес весь код (т.е. цикл с созданием соля) в OnGameModeInit и логировал длину получаемого соля (создавал массив с 65 ячейками для соля, так же как и в энуменаторе игрока), длина строк оказалось 67. Не знаю как так получалось. Изменил кол-во циклов с 65 на 64, длина строки изменилось на 64 (т.е. на нормальную длину, который должен был быть). Ну вкратце, проблема решена, но тему оставлю открытой, вдруг кто знает в чем именно заключалась моя ошибка.

Без кода - до сих пор непонятна твоя ошибка.

Geebrox
23.01.2017, 19:39
Без кода - до сих пор непонятна твоя ошибка.

Код был выше, прочитай ранее сообщение и поймешь.

- - - Добавлено - - -

Для того чтобы лишние вопросы не возникали, скину код еще раз:


stock CreatePlayerPassword(playerid, password[])
{
player[playerid][player_salt][0] = EOS;
player[playerid][player_password][0] = EOS;
new length = strlen(random_letters);
for(new i = 0; i < 65; i++)
{
player[playerid][player_salt][i] =
random_letters[random(length)];
}
SHA256_PassHash(password, player[playerid][player_salt],
player[playerid][player_password], 65);
return 1;
}

Логирование в OnGameModeInit:


new salt[64 + 1];
new length = strlen(random_letters);
for(new i = 0; i < 65; i++)
{
salt[i] = random_letters[random(length)];
}
printf(#%d, strlen(salt)); // выводило 67,крашев не было, выход за пределы массива тоже не было

Изменил на:


new salt[64 + 1];
new length = strlen(random_letters);
for(new i = 0; i < 64; i++)
{
salt[i] = random_letters[random(length)];
}
printf(#%d, strlen(salt)); // начал выводить 64 (длину которая должна была быть)

Изменил код в CreatePlayerPassword:


stock CreatePlayerPassword(playerid, password[])
{
player[playerid][player_salt][0] = EOS;
player[playerid][player_password][0] = EOS;
new length = strlen(random_letters);
for(new i = 0; i < 64; i++)
{
player[playerid][player_salt][i] =
random_letters[random(length)];
}
SHA256_PassHash(password, player[playerid][player_salt],
player[playerid][player_password], 65);
return 1;
}

Проблема решена, но остается вопрос, почему же строка получалась с длиной в 67 символов?

DeimoS
23.01.2017, 20:59
В первоначальном цикле у тебя итерации начинались с нуля до 64 включительно. Это и было проблемой. То бишь, с тем условием цикл совершал лишнюю итерацию.

Geebrox
23.01.2017, 21:31
В первоначальном цикле у тебя итерации начинались с нуля до 64 включительно. Это и было проблемой. То бишь, с тем условием цикл совершал лишнюю итерацию.

ну это я понял, но как в массив с 65 ячейками вместились 67 символов, и как вообще выполнилось 67 итераций (хотя может выполнились 65 итераций, не проверял, но откуда тогда взялись еще 2 символа)?