Хеш-функция – это такая разновидность функции, которая применяется в криптографических алгоритмах, электронных подписях, кодах аутентификации сообщений, контрольных суммах, паролях и целом ряде других элементов и процессов, требующих повышенного уровня защиты.
Эти функции нужны Python-разработчику для того, чтобы проверять дубликаты данных, файлов, проверять целостность данных в ходе передачи данных через сеть, безопасно хранить пароли в базах данных, и так далее. Сегодня поговорим о том, как использовать хеш-функции в Python.
Что такое хеш-функция в Python?
В языке Python хеш-функцией принимается определенная последовательность значений, которая имеет переменную длину (выраженную в байтах), а затем она переводится в последовательность с фиксированной длиной. Эта функция работает только в одну сторону. То есть, нельзя получить исходник из результата.
Если быть более точным, для повторного получения этого значения потребуется настолько много времени, что это попросту невыгодно. Поэтому такой метод защиты активно применяется на самых разных уровнях, в том числе, в интернет-банкинге.
Как называется то значение, которое возвращается хеш-функцией? Названия могут быть разными в различных источниках. Можно встретить название «хеш», дайджест сообщения, значение хеша либо «контрольная сумма». Обычно для ввода, который дается на эту функцию, хеш-функцией создается уникальный вывод. Тем не менее, в зависимости от алгоритма, возможно появление конфликта, связанного с теми математическими теориями, согласно которым эти функции работают.
Если говорить более точно, то сами хеш-функции – это не криптографический протокол. Это означает, что они не выполняют шифровки и дешифровки данных. Тем не менее, они – основа криптографических протоколов и инструментов.
Популярные хеш-функции в Python
Наиболее широко распространенными являются следующие хеш-функции:
- MD5. Этот алгоритм создает 128-битный хеш. Активно применяется, чтобы проверять целостность данных. Если в других областях использовать данный алгоритм, приложение будет иметь серьезные проблемы с безопасностью.
- SHA. Этот криптографический алгоритм гораздо более надежнее предыдущего. Создан в Соединенных Штатах и является составной частью Федерального стандарта обработки информации США. Длина сообщения может достигать 512 бит, а минимальная составляет 160 бит.
С помощью модуля hashlib, который входит в состав стандартной библиотеки Python, можно использовать наиболее популярные алгоритмы хеширования. Тем не менее, если у вас есть на компьютере OpenSSL, то эти алгоритмы также могут использоваться этим модулем.
Чтобы использовать код, который будет приводиться ниже, необходимо иметь версию Python, начиная 3.5. Но если есть желание попробовать воспользоваться этими примерами во второй версии этого языка, достаточно удалить вызовы attributems_available и algorithms_guaranteed.
Все начинается с импорта модуля hashlib.
import hashlib
Теперь для списка алгоритмов, которые можно использовать, используются algorithms_available и algorithms_guaranteed.
print(hashlib.algorithms_available)
print(hashlib.algorithms_guaranteed)
Посредством использования метода algorithms_available создается список всех алгоритмов, которые доступны в системе. В том числе, и те, которыми можно воспользоваться через OpenSSL. В этом примере в списке можно увидеть дубликаты названий. Лишь алгоритмы модуля перечисляются algorithms_guaranteed. Всегда в наличии md5, sha1, sha224, sha256, sha384, sha512.
Примеры кода
С помощью кода, который приводится ниже, мы пробуем закодировать строку «Hello World» в шестнадцатеричное значение. Именно оно и являет собой хеш.
Обратите внимание на этот фрагмент кода.
import hashlib hash_object = hashlib.md5(b'Hello World') print(hash_object.hexdigest())
Здесь b предшествует литералу строки, а также происходит конвертация в байты из-за того, что в качестве параметра функции хеширования можно использовать исключительно последовательность байтов. В прошлой версии библиотеки литерал строки принимался.
На практике, если вам требуется получить какую-то информацию, введенную пользователем, из консоли, а потом закодировать ее в хеш, то необходимо выполнить эту кодировку в последовательности байтов с помощью кода, подобного этому.
import hashlib mystring = input('Enter String to hash: ') # Предположительно по умолчанию UTF-8 hash_object = hashlib.md5(mystring.encode()) print(hash_object.hexdigest())
А что будет, если обработать строку «Hello World» с использованием MD5-алгоритма? В этом случае будет возвращен результат 0a4d55a8d778e5022fab701977c5d840bbc486d0.
Если мы хотим осуществить хеширование с использованием SHA1, то используется фрагмент, подобный следующему.
import hashlib hash_object = hashlib.sha1(b'Hello World') hex_dig = hash_object.hexdigest() print(hex_dig)
А теперь приведем некоторые примеры хеширования с использованием разных алгоритмов шифрования.
SHA224
import hashlib hash_object = hashlib.sha224(b'Hello World') hex_dig = hash_object.hexdigest() print(hex_dig)
SHA256
import hashlib hash_object = hashlib.sha256(b'Hello World') hex_dig = hash_object.hexdigest() print(hex_dig)
SHA384
import hashlib hash_object = hashlib.sha384(b'Hello World') hex_dig = hash_object.hexdigest() print(hex_dig)
SHA512
import hashlib hash_object = hashlib.sha512(b'Hello World') hex_dig = hash_object.hexdigest() print(hex_dig)
Особенности использования алгоритмов OpenSSL
Допустим, необходимо использовать алгоритм, который предоставлен OpenSSL. Чтобы сделать это, необходимо выполнить его поиск, используя algorithms_available.
В данном примере, на ПК доступен «DSA». Также возможно использование методов new и update.
import hashlib hash_object = hashlib.new('DSA') hash_object.update(b'Hello World') print(hash_object.hexdigest())
Хеширование паролей Python – реальный пример
Теперь необходимо привести пример, в котором хеширование паролей будет осуществляться, чтобы в дальнейшем сохранить их в базе данных. Здесь сначала пароли будут хешироваться, а потом сохраняться в базе данных.
Помимо этого, будет использоваться salt, которая является случайным набором значений, который добавляется к строке пароля перед тем, как будет использоваться хеш-функция. salt необходима, чтобы помешать злоумышленникам использовать такие методы взлома, как перебор по словарю или атаки радужной таблицы.
Конечно, это не защитит пользователя от других способов взлома паролей. Но это тема, которая является достаточно обширной, чтобы быть рассмотренной отдельно. Там много нюансов.
Если используется Python 3, то тогда пример хеширования паролей следующий.
import uuid import hashlib def hash_password(password): # uuid используется для генерации случайного числа salt = uuid.uuid4().hex return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt def check_password(hashed_password, user_password): password, salt = hashed_password.split(':') return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest() new_pass = input('Введите пароль: ') hashed_password = hash_password(new_pass) print('Строка для хранения в базе данных: ' + hashed_password) old_pass = input('Введите пароль еще раз для проверки: ') if check_password(hashed_password, old_pass): print('Вы ввели правильный пароль') else: print('Извините, но пароли не совпадают') А если вторая версия, то такой фрагмент. import uuid import hashlib def hash_password(password): # uuid используется для генерации случайного числа salt = uuid.uuid4().hex return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt def check_password(hashed_password, user_password): password, salt = hashed_password.split(':') return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest() new_pass = raw_input('Введите пароль: ') hashed_password = hash_password(new_pass) print('Строка для сохранения в базе данных: ' + hashed_password) old_pass = raw_input('Введите пароль еще раз для проверки: ') if check_password(hashed_password, old_pass): print('Вы ввели правильный пароль') else: print('Извините, но пароли не совпадают')
Выводы
Криптографические алгоритмы лежат в основе не только защиты паролей. Так, они активно используются для майнинга криптовалют.
Фактически они используются для любой ситуации, когда требуется обеспечение защиты данных в незащищенной среде (а интернет, безусловно, является такой).
Если еще больше обобщать, криптография нужна в любой ситуации, когда требуется конфиденциальность. Что под ней подразумевается? Прежде всего, защита от тех лиц, которые не имеют права доступа.
Например, в тех же криптовалютах криптографические алгоритмы используются, например, чтобы зашифровать ключ от кошелька. Каждый кошелек состоит из двух частей:
- Публичной. Открытый шестнадцатеричный номер, который генерируется на основе приватного ключа. Используется для получения транзакций на биткоин-кошелек.
- Приватной. Приватный кошелек невозможно воссоздать, имея публичный, поскольку сама функция односторонняя. Используется для управления средствами, которые находятся на кошельке. В том числе, и для отправки этих средств на чужой кошелек.
Таким образом, криптография – это будущее. И чем больше мы двигаемся в него, тем более полезной эта тема становится.