PDA

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



AMD
17.03.2016, 23:36
Здравствуйте. Возникла проблемка:

В создании аккаунта добавил md5_hash


stock CreateNewAccount(playerid, password[])
{
new query_string[512];
format(query_string, sizeof(query_string), "INSERT INTO `accounts` (`Player_Name`, `Password`, `Admin`, `Cash`, `Skin`, `Ban`) VALUES ('%s', '%s', '0', '0', '0', '0')",
pInfo[playerid][pName], MD5_Hash(MD5_Hash(password)));
mysql_function_query(mID, query_string, false, "", "");
return 1;
}

Пароли шифрует без вопросов. Проблема в том, что при авторизации он их не расшифровывает.


if(!strcmp(pInfo[playerid][pPassword], inputtext))

//MD5_Hash(MD5_Hash(password))
{
new query_string[52+MAX_PLAYER_NAME];
format(query_string, sizeof(query_string), "SELECT * FROM `accounts` WHERE `player_name` = '%s'", pInfo[playerid][pName]);
mysql_function_query(mID, query_string, true, "UploadPlayerAccount","i", playerid);
}
else ErrorDialogMessage(playerid, dLogin, 2);
return 1;

Пробовал разными способами:


if(!strcmp(MD5_Hash(MD5_Hash(pInfo[playerid][pPassword])), inputtext))

Потом так:


format(query_string, sizeof(query_string), "SELECT * FROM `accounts` WHERE `player_name` = '%s' AND `Password` = '%s'", pInfo[playerid][pName], MD5_Hash(MD5_Hash(pInfo[playerid][pPassword])));

Кто поможет решить данный вопрос?

VVWVV
18.03.2016, 00:07
1. Уже небезопасно хешировать пароли с помощью алгоритма md5, используйте новую функцию в pawn - SHA256_PassHash (кэшированная версия (https://webcache.googleusercontent.com/search?q=cache:j7b12sDXY3sJ:https://wiki.sa-mp.com/wiki/SHA256_PassHash+&cd=1&hl=en&ct=clnk&gl=ru)).
2. Нельзя расшифровать пароль (не говоря о сайтах).
3.1. Как вы получаете значение pInfo[playerid][pPassword].
3.2.
if(!strcmp(MD5_Hash(MD5_Hash(pInfo[playerid][pPassword])), inputtext))
Зачем вы хешируете пароль ещё раз? Как минимум, если думать логически, вы должны захешировать inputtext, а после - сравнить.
Тоже самое:

format(query_string, sizeof(query_string), "SELECT * FROM `accounts` WHERE `player_name` = '%s' AND `Password` = '%s'", pInfo[playerid][pName], MD5_Hash(MD5_Hash(pInfo[playerid][pPassword])));

AMD
18.03.2016, 01:04
Советовали юзать двойное хеширование.
SHA256_PassHash выпущен с 0.3.7, а сервер у меня 0.3e версии.

То есть, вы предполагаете делать так?

if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)

VVWVV
18.03.2016, 01:08
Советовали юзать двойное хеширование.
А SHA256_PassHash выпущен с 0.3.7, а сервер у меня 0.3e версии.

То есть, вы предполагаете делать так?

if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)

Да, ибо в pInfo[playerid][pPassword] уже загружен захешированный пароль из базы данных.

P.S. используйте Соль (https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%BB%D1%8C_(%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F)).

AMD
18.03.2016, 01:16
Забил данную проверку, пароль ни хешированный ни какой не принимает.
Если пробовать так:

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)

Будет:
warning 213: tag mismatch

VVWVV
18.03.2016, 01:19
Забил данную проверку, пароль ни хешированный ни какой не принимает.
Если пробовать так:

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)

Будет:
warning 213: tag mismatch


if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)
тоже самое:

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]))

AMD
18.03.2016, 01:27
if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)
тоже самое:

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]))

Всё, вопрос улажен.
Только в данной проверке.

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]))
! лишний.

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

Казалось бы, но нет.

Теперь можно водить абсолютно любые пароли.

VVWVV
18.03.2016, 01:31
Всё, вопрос улажен.
Только в данной проверке.

if(!strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]))
! лишний.

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

Казалось бы, но нет.

Теперь можно водить абсолютно любые пароли.

Нет. Если строки совпали, то функция strcmp возвращает нуль. Соответственно, знак ! очень нужен.

На wiki.sa-mp.com написано:

Return Values:
0 if strings match each other on given length;
1 o r -1 if some character do not match: string1[i] - string2[i] ('i' represents character index starting from 0);
difference in number of characters if one string matches only part of another string.

Лучше используйте так:

if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)
{
/* Если строки совпали */
}

AMD
18.03.2016, 01:38
case dLogin:
{
if(!response)
{
SPD(playerid, dLogin, DSM, "Оповещение", "{FFFFFF}Вы были кикнуты с сервера.\n{FF0000}Причина: Отказ от авторизации.\n{FFFFFF}Для выхода с сервера введите \"/q\" в чат", "Вход", "Выход");
return Kick(playerid);
}
if(!strlen(inputtext)) return ErrorDialogMessage(playerid, dLogin, 0);
for(new i = strlen(inputtext)-1; i != -1; i--)
{
switch(inputtext[i])
{
case '0'..'9', 'а'..'я', 'a'..'z', 'А'..'Я', 'A'..'Z': continue;
default: return ErrorDialogMessage(playerid, dLogin, 1);
}
}
if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)
{
new query_string[52+MAX_PLAYER_NAME];
format(query_string, sizeof(query_string), "SELECT * FROM `accounts` WHERE `player_name` = '%s'", pInfo[playerid][pName]);
mysql_function_query(mID, query_string, true, "UploadPlayerAccount","i", playerid);
}
return ErrorDialogMessage(playerid, dLogin, 2);
}

Так и сделано,в итоге принимать пароль никакой не хочет.

VVWVV
18.03.2016, 01:43
case dLogin:
{
if(!response)
{
SPD(playerid, dLogin, DSM, "Оповещение", "{FFFFFF}Вы были кикнуты с сервера.\n{FF0000}Причина: Отказ от авторизации.\n{FFFFFF}Для выхода с сервера введите \"/q\" в чат", "Вход", "Выход");
return Kick(playerid);
}
if(!strlen(inputtext)) return ErrorDialogMessage(playerid, dLogin, 0);
for(new i = strlen(inputtext)-1; i != -1; i--)
{
switch(inputtext[i])
{
case '0'..'9', 'а'..'я', 'a'..'z', 'А'..'Я', 'A'..'Z': continue;
default: return ErrorDialogMessage(playerid, dLogin, 1);
}
}
if(strcmp(MD5_Hash(MD5_Hash(inputtext)), pInfo[playerid][pPassword]) == 0)
{
new query_string[52+MAX_PLAYER_NAME];
format(query_string, sizeof(query_string), "SELECT * FROM `accounts` WHERE `player_name` = '%s'", pInfo[playerid][pName]);
mysql_function_query(mID, query_string, true, "UploadPlayerAccount","i", playerid);
}
return ErrorDialogMessage(playerid, dLogin, 2);
}

Так и сделано,в итоге принимать пароль никакой не хочет.

Я думал, что у вас это все в отдельной функции (паблике). Теперь всё понятно, у вас не загружено значение из базы данных в массив (pInfo[playerid][pPassword]), из-за этого ошибка.

UPD:
Это вам не mxINI.


public
OnPlayerConnect(playerid)
{

new query_string[52+MAX_PLAYER_NAME];
mysql_format(mID, query_string, sizeof query_string, "SELECT * FROM `accounts` WHERE `player_name` = '%s' LIMIT 1", pInfo[playerid][pName]);
mysql_tquery(mID, query_string, "OnAccountResponse", "i", playerid);
}

forward OnAccountResponse(playerid);
public OnAccountResponse(playerid)
{
new rows, fields;
cache_get_data(rows, fields);
if (rows)
{
/* если аккаунт существует, т.е. rows > 0 */
// Загружаем, выводим диалоги и т.п.

}
else
{
/* если аккаунт не существует, т.е. rows == 0 */
}
}

P.S. хороший урок (http://pro-pawn.ru/showthread.php?10548) от DeimoS.
P.S. Если бы вы ответил на:

3.1. Как вы получаете значение pInfo[playerid][pPassword].
было бы все быстрее и проще.