Политика безопасности ОС не позволяет задавать для учетных записей пользователей пароли, совпадающие с их именами. Для этого перед добавлением нового пользователя в базу вызывается функция CheckUser(). При ее успешном выполнении (возвращаемое значение = 0) в базу добавляется новая запись, содержащая имя учетной записи пользователя и хеш-значение пароля, полученное с помощью функции Hash().
Си |
int CheckUser(char* username, char* password) { for (int i=0; i<strlen(username); i++) { if ( (username[i] >= 0x30 &&
(username[i] >= 0x41 &&
(username[i] >= 0x61 &&
) continue; else return 1; } for(int i=0; i<strlen(password); i++) { if (password[i] >= 0x23 &&
continue; else return 1; } if (stricmp(username, password) != 0) return 0; else return 1; } |
const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890";
char* Hash(char* str) { const int p = 19; int Nstr = 32; const int Hsize = Nstr / 2; unsigned short int hash = 0, p_pow = 1; char *buf = new char[Nstr + 1]; int size = 0; char *res = new char[Hsize + 1]; while (str[size] != '\0' && size < Nstr) { buf[size] = str[size]; size++; } for (int i = size; i < Nstr; i++) { buf[i] = '0' + (i - size); } buf[Nstr] = '\0'; for (int i = 0; i < Nstr; i+=2) { hash += (buf[i] - '0' + 1) * p_pow; p_pow *= p; hash += (buf[i + 1] - '0' + 1) * p_pow; p_pow *= p; res[i / 2] = letters[hash % strlen(letters)]; } res[Hsize] = '\0'; return res; } |
Администратор периодически выполняет проверку базы пользователей и блокирует учетные записи, хеш-значения от имени которых совпадают с хеш-значениями их паролей. Приведите пример имени и пароля для учетной записи, которая удовлетворяет заданной политике безопасности, но будет заблокирована администратором в ходе проверки, и обоснуйте почему.
Проанализировав функцию CheckUser(), можно сделать вывод о том, что она действительно не позволяет создавать пользователей, пароль которых совпадает со значением имени его учетной записи. Следовательно, можно сделать вывод, что причина возникновения нарушений связана с ошибкой в вычислении хеш-значения пароля.
Действительно, нарушения при добавлении пользователя в базу могли произойти из-за возможности возникновения коллизий при использовании функции Hash()(ситуаций, когда для некоторых различных данных значения хеш-функции совпадают) Рассмотрим одну из причин возникновения коллизии. Из анализа кода:
for (int i = size; i < Nstr; i++)
{
buf[i] = '0' + (i - size);
}
видно, что в случае если длина пароля менее 32 символов, то для вычисления хеш-значения его длина увеличивается до 32 символов. При этом в вычислении результирующего хеш-значения (переменная res) участвуют только первые 32 символа пароля (или его расширенной до 32 символов копии):
for (int i = 0; i < Nstr; i+=2)
{
hash += (buf[i] - '0' + 1) * p_pow;
p_pow *= p;
hash += (buf[i + 1] - '0' + 1) * p_pow;
p_pow *= p;
res[i / 2] = letters[hash % strlen(letters)];
}
Следовательно, если длина пароля будет превышать 32 символа, то начиная с 33 позиции его символы не будут участвовать в формировании хеш-значения. Таким образом, возникновение ситуации, когда хеш-значения от имени учетной записи пользователя и заданного для него пароля совпадают, возможно, например, при одновременном выполнении следующих условий:
пароль отличается от логина;
длина логина 32 символа или более;
длина пароля больше 32-х символов.
первые 32 символа логина и пароля совпадают.
В качестве примера можно указать любую пару Имя-Пароль, удовлетворяющую следующим критериям:
Пароль отличается от Имени;
длина Имени 32 символа или более;
длина Пароля больше 32-х символов;
первые 32 символа Имени и Пароля совпадают.
Например:
Имя – 123…901…01…012;
Пароль – 123…901…01…012xxx ( где xxx – любое количество (>1) любых символов)