2025 [8-10] Хэширование

Сотрудник отдела информационной безопасности компании «AC-Крипто» на рабочем столе системного администратора обнаружил ссылку на git-репозиторий. В репозитории содержится:

-     описание алгоритма хеширования;

-     исходный код функции хеширования;

-     файл test_results.txt.

Из описания стало известно, что алгоритм хэширования используется администратором для хранения паролей. Алгоритм предполагает использование «соли» – 4-символьная строка, состоящая из заглавных и строчных латинских букв (A-Z, a–z), добавляемая к хешируемой строке.

Исходный код функций хеширования представлен в листинге.

 

Листинг 1. Исходный код функций хеширования

Python

# Нормализует соль до ровно 4 символов

def normalize_salt(salt: str) -> str:

    # Если соль пустая - возвращаем пустую строку

    if len(salt) == 0:

        return ''

    if len(salt) < 4:

        # Если соль короче 4 символов - повторяем её по кругу

        return ''.join(salt[i % len(salt)] for i in range(4))

    else:

        # Если длиннее 4 - берём только первые 4 символа

        return salt[:4]

 

# Добавляет соль в пароль

def weave_salt(password: str, salt: str) -> str:

    salt = normalize_salt(salt)

    half = len(password) // 2 # Находим середину пароля (целочисленное деление)

return password[:half] + salt + password[half:] + salt

 

# Вычисляет хеш строки

def custom_hash(s: str) -> str:

    # Начальные значения - 8 магических байт (основа хеша)

    h = [0xEF, 0xAC, 0xEB, 0xCA, 0xAD, 0xDF, 0xBE, 0xDA]

    for c in s:

        # Для каждого элемента h[i] умножаем его на 65537,

        # затем на (i+1)

        # и добавляем ASCII-код символа c

        h = [ (h[i] * 65537 * (i+1) + ord(c)) % (2**16) for i in range(len(h))]

    # Преобразуем число в HEX-формат и конвертируем в строку

    hash_str = ''.join(f"{x:04x}" for x in h)

    # Берём последние 4 символа исходной строки

    hash_4 = s[-4:]

    # Переводим каждый символ в 2-значный HEX-код

    salt = ''.join(f"{ord(ch):02x}" for ch in hash_4)

    # Модифицируем последние 8 символов хеша

    return hash_str[:-8] + salt

 

PASSWORD = ""

REAL_SALT = ""

woven = weave_salt(PASSWORD, REAL_SALT)

hash_val = custom_hash(woven)

print(f"Сгенерированный хеш: {hash_val}")

С++

#include <iostream>

#include <string>

#include <sstream>

#include <iomanip>

using namespace std;

 

// Функция normalize_salt — нормализует соль до 4 символов

string normalize_salt(string salt) {

    // Если соль пустая — возвращаем пустую строку

    if (salt.length() == 0) {

        return "";

    }

    // Если соль короче 4 символов — повторяем её символы по кругу

    if (salt.length() < 4) {

        string result = "";

        for (int i = 0; i < 4; i++) {

            result += salt[i % salt.length()];

        }

        return result;

    }

    else {

        // Берём подстроку: начиная с позиции 0, длиной 4 символа

        return salt.substr(0, 4);

    }

}

 

// Функция weave_salt — добавляет соль в пароль

string weave_salt(string password, string salt) {

    salt = normalize_salt(salt);

    int half = password.length() / 2;

    string first_part = password.substr(0, half);     // первая половина пароля

    string second_part = password.substr(half);       // вторая половина пароля

    return first_part + salt + second_part + salt;

}

 

// Функция custom_hash — вычисляет хеш строки

string custom_hash(string s) {

    // Начальные значения - 8 магических байт (основа хеша)

    unsigned int h[8] = { 0xEF, 0xAC, 0xEB, 0xCA, 0xAD, 0xDF, 0xBE, 0xDA };

    for (char c : s) {

        // Для каждого элемента h[i] умножаем его на 65537,

        // затем на (i + 1)

        // и добавляем ASCII-код символа c

        for (int i = 0; i < 8; i++) {

            h[i] = (h[i] * 65537*(i+1) + (unsigned int)c) % 65536;

        }

    }

    // Собираем строку из 8 * 4 = 32 hex-символов

    // Каждое число форматируется как 4 hex-цифры

    stringstream hash_stream;

    for (int i = 0; i < 8; i++) {

        hash_stream << hex << setw(4) << setfill('0') << h[i];

    }

    string hash_str = hash_stream.str(); // итого 32 символа

    // Берём последние 4 символа исходной строки

    string hash_4 = s.substr(s.length() >= 4 ? s.length() - 4 : 0);

    // Переводим каждый символ в 2-значный HEX-код

    string salt_hex = "";

    for (char ch : hash_4) {

        stringstream ss;

        ss << hex << setw(2) << setfill('0') << (int)(unsigned char)ch;

        salt_hex += ss.str();

    }

    // Модифицируем последние 8 символов хеша

    string final_hash = hash_str.substr(0, hash_str.length() - 8) + salt_hex;

    return final_hash;

}

 

// Главная функция — точка входа программы

int main() {

    setlocale(LC_ALL, "ru");

    string PASSWORD = "";  

    string REAL_SALT = "";  

    string woven = weave_salt(PASSWORD, REAL_SALT);

    string hash_val = custom_hash(woven);

    cout << "Сгенерированный хеш: " << hash_val << endl;

    return 0;

}

 

В файле test_results.txt содержатся следующие строки:

password

TEST

06e2ee6e82daf6f0d630d21a54455354

 

Определите, какая фраза использовалась для подмешивания («соль»), если известно, что пароль – ikbmtuci, а его хэш-значение – 06955dcf1ae16061178b4b9b56494345.

 

Показать подсказку

Показать решение

Показать ответ




<< Назад в раздел (Все задания)

Ваше сообщение получено!