Механизм хэширования
Давайте пошагово рассмотрим принцип работы и механизм хэш-функции MD5:
Шаг 1. Выравнивание потока
Преобразуем строку «MD5» в двоичный код: 010011010100010000110101
Теперь, посчитав количество символов в данной последовательности, мы приравняем q к полученному количеству. В данном случае q = 24
Переводим q в 2-ный код (64 бита) с ведущими нулями: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 1000
Далее мы дописываем единичный бит в конце потока (байт 80h) и необходимое число нулевых бит.
В последовательности мы приписываем нули до тех пор, пока длина последовательности не станет по модулю 512 равна 448 010011010100010000110101 1 0{423}
({423} – оставшееся число нулей(0), которые нужно дописать)
Далее к последовательности дописываются младшие 32 бита числа q, а затем старшие. 010011010100010000110101 1 0{423} 0000 0000 0000 0000 0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0000 0000
(
)
Сейчас же длина последовательности становится кратной 512. Полученную последовательность назовем S.
Для подсчета результата используются четыре двойных слова (32 бита). Эти двойные слова инициализируются следующими шестнадцатеричными значениями, где первым следует самый младший байт:
A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10
Потребуются 4 функции для четырёх раундов. Введём функции от трёх параметров — слов, результатом также будет слово:
1-й
раунд:
,
2-й
раунд:
,
3-й
раунд:
,
4-й
раунд:
,
X,
Y, Z — это
двойные слова.
Результаты
функций,
также
двойные слова.
Для подсчета
используется еще одна функция (назовем
её
W). Она
обрабатывает данные и возвращает
результат.
На рисунке схематически изображена функция. Слева — входные данные, справа — выходные.
Запоминаем первые 512 бит последовательности S.
Вызываем функцию W. Параметры A, B, C, D — это текущие значения соответствующих двойных слов. Параметр T — это запомненные 512 бит.
Прибавляем к A A0.
B=B+B0.
C=C+C0.
D=D+D0.
Если длина последовательности 0, выходим.
Переходим к шагу 1.
Безопасность и Актуальность
На данный момент в чистом виде данные хэш-функции почти не используется, так как это является довольно бессмысленным делом, ведь существует множество способов легко расшифровать данные алгоритмы, используя брут, подбор по словарю, или же радужные таблицы (RainbowCrack).
RainbowCrack — является методом нахождения прообраза хэша из заданного множества. Он основан на генерации цепочек хэшей, чтобы по получившейся базе вести поиск заданного хэша. Создание радужных таблиц занимает достаточно много времени и памяти, но последующий взлом производится очень быстро, что полностью оправдывает потраченное время. Основная идея данного метода — достижение компромисса между временем поиска по таблице и занимаемой памятью.
Во избежание взлома и в целях повысить защиту были придуманы так называемые «соли».
В криптографии соль - это строка случайных данных, которая подается на вход хэш-функции вместе с исходными данными. Используется для удлинения строки пароля, что осложняет восстановление группы исходных паролей за один проход полного перебора или с помощью предварительно построенных радужных таблиц. Однако, этим соль не защищает от полного перебора каждого пароля в отдельности.
При использовании соли, безопасность и защита данных значительно возрастает.
Ниже будет приведен пример использования соли в MD5 на php и в MD5 + SHA512 в языке Python.
PHP:
$password = 'password'; //Сам пароль
$hash1 = md5($password);
//Хешируем первоначальный пароль
$salt = 'sflprt49fhi2';
//Генерируем случайный набор символов (соль)
$hash2 = md5($hash1 . $salt);
//Складываем старый хеш с солью и пропускаем через функцию md5()
PYTHON:
import hashlib
password = "admin"
salt = "GvNsjh49w"
m = hashlib.md5()
m.update(bytes(password, "utf-8"))
a = hash(m.hexdigest()), m.hexdigest(), password
md_hash = a[1]
print(md_hash)
#получаем - 21232f297a57a5a743894a0e4a801fc3
sha = hashlib.sha1(bytes(salt, "utf-8"))
dig = sha.hexdigest()
dig
#получаем - 68094f2cd880e85d4809477afe9618d58ee74d38
hash1 = md_hash+dig #Складываем наш пароль в md5 и соль в sha1
hash1
#получаем - 21232f297a57a5a743894a0e4a801fc368094f2cd880e85d4809477afe9618d58ee74d38
hash_salt = hashlib.sha512(bytes(hash1, "utf-8"))
#Хэшируем сумму в sha512
finally_salt = hash_salt.hexdigest()
finally_salt
#На выходе мы получаем - 324544ffd3d3c1b5d0bc43c9a36b8fd5b67f1b6a38e62364d1a613ac13b997c511a77e346441b429d46eedcfc6f50c7976f4758c4f1317b2280034e28cfe0b78 (sha512)
