У цьому матеріалі мова піде про бібліотеку brcypt
та те, як її використовувати на приктиці. Ми поговоримо про її призначення, розберемо функціонал і тд.
Для чого потрібна бібліотека bcrypt?
Бібліотека bcrypt
— це спеціальний алгоритм хешування. Під словом “хешування“ мається на увазі перетворення наших вхідних даних у деякий рядок з фіксованою довжиною, який і називається хешем.
Тобто хешування не дає умовному зловмиснику отримати дані, наприклад, хешування застосовується по відношенню до паролів у базі даних. Насправді паролі не зберігаються у базі даних відкрито, вони хешуються і у базах даних зберігається саме їх хеш, а не самі паролі.
Встановлення бібліотеки
Windows:
pip install bcrypt
MacOS:
pip3 install bcrypt
Linux:
pip install bcrypt
Хешування за допомогою bcrypt
Тепер розглянемо як згенерувати хеш за допомогою bcrypt
. Ось приклад програми, яка генерує хеш:
import bcrypt
password = "fisherman204512"
password_to_bytes = password.encode(encoding="utf-8")
salt = bcrypt.gensalt()
hash_password = bcrypt.hashpw(password_to_bytes, salt)
print(hash_password)
b'$2b$12$zh5gI.LiCBuMdTPw9LpJzORv.vE976GN4RZrk5mqzchaY9FTEGtry'
Рядки коду | Пояснення |
---|---|
| Імпортуємо бібліотеку |
| Оголошуємо змінну |
| Перетворюємо наш щойно оголошений пароль у байт рядок. |
| Генеруємо сіль. |
| Генеруємо хеш, передаючи у якості параметрів пароль, перетворений на байт рядок та сіль. |
Сіль — це деякий випадково згенерований рядок у хеші, який додається до самого хеша для того, щоб однакові паролі мали різний хеш.
Тобто саме завдяки солі кожен наступний запуск програми генерує новий хеш, хоча пароль залишається той самий. Ось результат повторного запуску нашої попередньої програми, але вже з новим хешем у результаті:
b'$2b$12$rZjZodP2jg6KQgN/3x8y4e1SdUxXoPVmj/Me47M.E7RaaAYwCO5ma'
Тепер можемо розглянути ще один приклад, де ми не перетворюємо рядок у байт рядок, а просто оголошуємо його одразу:
password = b"qwerty"
salt = bcrypt.gensalt()
hash_password = bcrypt.hashpw(password, salt)
print(hash_password)
b'$2b$12$Oivb5HmRJMIkTrBUhXjjPe0pWOM75QVTfpcHohTpXbZp8M3pG09aa'
Параметри солі та структура хеша
У функції gensalt()
є параметри rounds
та prefix
. Параметр rounds
визначає те, скільки разів наш хеш буде проходити через алгоритм bcrypt
. Від параметра rounds
залежить і надійність хешу, і також це впливає на час його генерації. Тобто чим більше значення приймає rounds
, тим довше генерується хеш. Параметр prefix
у свою чергу просто вказує на версію алгоритму bcrypt
. Ось приклад застосування цих двох параметрів та як це відобразиться на хеші:
password = b"goldenApple"
salt = bcrypt.gensalt(rounds=14, prefix=b"2b")
hash_password = bcrypt.hashpw(password, salt)
print(salt)
print(hash_password)
b'$2b$14$OVVtHVZ3EziSvwpakyk3pulOBHMIQyO4za7JgIxgW3.A3zngmf7Ay'
Тепер розберемо отриманий результат. Для цього скористаємося наведеною нижче картинкою і таблицею з поясненнями щодо структури хеша.

Частина хеша | Значення частини |
---|---|
Рожевий колір. | Сіль хешу. Тобто це те значення, яке ми генеруємо за допомогою функції |
Червоний колір. | Це хеш самого паролю. |
Зелений колір. | Це версія алгоритму |
Помаренчевий колір. | Це кількість ітерацій, яку проходить наш хеш через алгоритм |
Тепер ми зрозуміли, що хеш ховає все-таки у собі якісь дані, а не є просто зашифрованим рядком. Пропоную подивитися також на ще один подібний приклад, тільки з іншими значеннями параметрів:
password = b"super_milk"
salt = bcrypt.gensalt(rounds=18, prefix=b"2a")
hash_password = bcrypt.hashpw(password, salt)
print(hash_password)
b'$2a$18$1TN9pEm4AQktL4/GUX3/jOL.9.QrokmYOJ9pMKbnoylx1RwtN.YTC'
Ось, тепер вже нові значення rounds
та prefix
, які також можна побачити у новому хеші. За замовчуванням у хешах використовується версія 2b
, якщо параметр prefix
взагалі не вказаний.
Порівняння хеша та пароля
За допомогою функції checkpw()
, яка повертає True
, якщо хеш відповідає паролю та False
— якщо ні. ми можемо перевірити, чи відповідає хеш паролю. Приклад застосування checkpw()
наведений нижче:
password = b"qwerty"
salt = bcrypt.gensalt()
hash_password = bcrypt.hashpw(password, salt)
print(bcrypt.checkpw(password, hash_password))
True
Ми взяли за основу хеш та пароль з попереднього прикладу, тому у даному випадку ми отримали True
у результаті. Тепер використаємо інший хеш та передамо його у функцію:
password = b"qwerty"
hash_password = b'$2b$12$rZjZodP2jg6KQgN/3x8y4e1SdUxXoPVmj/Me47M.E7RaaAYwCO5ma'
print(bcrypt.checkpw(password, hash_password))
False
Тепер хеш невідповідає паролю і звісно ми отримали False
.
Підсумок
Отже, у підсумку ми розібрали бібліотеку bcrypt
, ознайомилися з її функціями та розглянули структуру хеша. Сподіваюся, що дана стаття була цікава та по-справжньому корисна для вас. Дякую за увагу!