Хэш-пароли с использованием библиотеки bcrypt в Python
Веб-сервисы и веб-сайты хранят хешированные версии ваших паролей, что означает, что ваш настоящий пароль не виден и не хранится в их базе данных, вместо этого сохраняется строка символов фиксированной длины.
Хеширование — это метод обеспечения безопасности, используемый для защиты ваших паролей или текстов, хранящихся в базах данных. Хэш-функция используется для генерации строки уникальных символов фиксированной длины из пароля, предоставленного пользователем.
Давайте посмотрим, как осуществляется хеширование. В этой статье вы будете использовать библиотеку bcrypt для хеширования пароля пользователя, а затем сравните этот хешированный пароль с фактическим паролем в Python. Вы также узнаете больше о библиотеке bcrypt.
Установка bcrypt
Откройте окно терминала и выполните следующую команду, чтобы установить библиотеку bcrypt с помощью pip
.
pip install bcrypt
Хэш-пароль с использованием bcrypt
В этом разделе вы увидите функции, предоставляемые библиотекой bcrypt, которые помогут вам генерировать соль и хэш-значения.
import bcrypt
# Password to Hash
my_password = b'Sachinfromgeekpython'
# Generating Salt
salt = bcrypt.gensalt()
# Hashing Password
hash_password = bcrypt.hashpw(
password=my_password,
salt=salt
)
print(f"Actual Password: {my_password.decode('utf-8')}")
# Print Hashed Password
print(f"Hashed Password: {hash_password.decode('utf-8')}")
Приведенный выше код импортирует библиотеку bcrypt для хеширования пароля. Тестовый пароль предоставляется в байтах и хранится внутри переменной my_password
.
Код использует функцию gensalt()
из библиотеки bcrypt для генерации соли — строки символов для повышения безопасности.
Соль — это случайная и уникальная строка символов, объединенная с паролем перед хешированием для обеспечения дополнительной безопасности. Она всегда будет уникальной. Если у двух пользователей одинаковый пароль, их хешированные пароли будут разными.
Затем фактический пароль (my_password
) и соль (salt
) передаются в функцию hashpw()
из библиотеки bcrypt для получения хэш-значения фактического пароля.
Наконец, действительные и хешированные пароли декодируются и распечатываются.
Actual Password: Sachinfromgeekpython
Hashed Password: $2b$12$RF6JLXecIE4qujuPgTwkC.GN2BsOmGf8Ji10LyquoBaHkHWUWgiAm
Проверьте пароль с помощью bcrypt
Теперь, когда вы хэшировали пароль, следующим шагом будет проверка фактического хеш-значения пароля с паролем, предоставленным пользователем.
import bcrypt
# Password to Hash
my_password = b'Sachinfromgeekpython'
# Generating Salt
salt = bcrypt.gensalt()
# Hashing Password
hash_password = bcrypt.hashpw(
password=my_password,
salt=salt
)
# User-provided Password
user_password = b'Sachinfromgeekpython'
# Checking Password
check = bcrypt.checkpw(
password=user_password,
hashed_password=hash_password
)
# This will print True or False
print(check)
# Verifying the Password
if check:
print("Welcome to GeekPython.")
else:
print("Invalid Credential.")
Приведенный выше код использует функцию checkpw()
из библиотеки bcrypt для проверки пароля, предоставленного пользователем, по хешированному паролю. Хешированный пароль (hash_password
) и пароль, предоставленный пользователем (user_password
), передаются внутри функции, а результат сохраняется внутри проверочной переменной.
Затем код печатает проверочную переменную для получения результата. В конце для проверки пароля используется оператор if-else
.
True
Welcome to GeekPython.
Значение True
в приведенном выше выводе означает, что хешированный пароль соответствует паролю, предоставленному пользователем, что делает первое условие истинным.
Хэш-пароль с использованием KDF (функция получения ключа)
KDF (функция деривации ключа) используется для повышения безопасности при хешировании паролей. KDF используются для получения ключей из паролей в целях аутентификации, включая соль и количество раундов.
import bcrypt
password = b'Sachinfromgeekpython'
salt = bcrypt.gensalt()
# Using KDF from bcrypt Lib
key = bcrypt.kdf(
password=password,
salt=salt,
desired_key_bytes=32,
rounds=200
)
# Print Generated Key
print(f"Key: {key}")
В приведенном выше коде используется функция kdf()
из библиотеки bcrypt для получения ключа из пароля. Функция передается с четырьмя параметрами:
Password
: для этого параметра установлена переменная пароля, которая содержит строку байтов.salt
: для этого параметра установлена переменнаяsalt
, которая содержит уникальную соль фиксированной длины.desired_key_bytes
: для этого параметра установлено значение 32, что соответствует желаемой длине производного ключа, который нам нужен. Вы можете установить желаемую длину.rounds
: для этого параметра установлено значение 200, что представляет собой количество итераций, позволяющих сделать получение ключа более интенсивным в вычислительном отношении и повысить безопасность. Чем выше раунды, тем выше безопасность, но тем больше ресурсов и времени требуется.
Наконец, выводится результат, сохраненный в ключевой переменной.
Key: b'\xc4#VW\x9a\x16\xdbG?\x11\xa9\xf7\xbd\x88"7+zxo\xfe@\xce\xab\x89\xc3g\x1c\xec~\xbe\xf7'
Проверка пароля с помощью KDF
import bcrypt
password = b'Sachinfromgeekpython'
salt = bcrypt.gensalt()
# Using KDF from bcrypt Lib
key = bcrypt.kdf(
password=password,
salt=salt,
desired_key_bytes=32,
rounds=200
)
# User-provided Password
user_password = b'Sachinfromgeekpython'
# Deriving Key from User-provided Password
user_key = bcrypt.kdf(
password=user_password,
salt=salt,
desired_key_bytes=32,
rounds=200
)
# Verifying the Password
if user_key == key:
print("Welcome to GeekPython.")
else:
print("Invalid Credential.")
Код извлекает ключ из пароля, предоставленного пользователем (user_password
), и сохраняет его внутри переменной user_key
.
Затем код проверяет производные ключи на основе предоставленного пользователем пароля (user_key
) и фактического пароля (password
).
Welcome to GeekPython.
Вывод показывает, что ключ, полученный из пароля, предоставленного пользователем, соответствует ключу, полученному из фактического пароля.
Настройка salt
Функция gensalt()
принимает два параметра: rounds
и prefix
, которые позволяют вам настроить количество раундов хеширования, применяемых к соли и префиксу соли.
import bcrypt
# Customize Salt
salt = bcrypt.gensalt(
rounds=30,
prefix=b'2a'
)
# Print Generated Salt
print(salt.decode('utf-8'))
Приведенный выше код настраивает генерацию соли, передавая параметр rounds
, для которого установлено значение 30, и параметр prefix
, для которого установлено значение b'2a'
, в функцию gensalt()
.
$2a$30$5uKaXaXVceqCjmKkPf2mnu
Вы можете заметить, что вначале после $
стоит префикс 2a
, а сразу после этого 30 указывает количество раундов.
Заключение
Хеширование пароля предотвращает раскрытие фактического пароля пользователя злоумышленникам. Хэш-функция, которая представляет собой просто математическую функцию, используется для получения хэш-значения пароля.
В этой статье вы научились хешировать пароль пользователя с помощью библиотеки bcrypt
в Python, а затем сверять полученное хэш-значение с паролем, предоставленным пользователем. Кроме того, вы видели KDF (функцию деривации ключей), которая обеспечивает дополнительную безопасность хеширования.