# `hashlib` — Secure hashes and message digests

Вихідний код: Lib/hashlib.py

This module implements a common interface to many different hash algorithms. Included are the FIPS secure hash algorithms SHA224, SHA256, SHA384, SHA512, (defined in the FIPS 180-4 standard), the SHA-3 series (defined in the FIPS 202 standard) as well as the legacy algorithms SHA1 (formerly part of FIPS) and the MD5 algorithm (defined in internet RFC 1321).

Примітка

Якщо вам потрібні хеш-функції adler32 або crc32, вони доступні в модулі `zlib`.

## Хеш-алгоритми

There is one constructor method named for each type of hash. All return a hash object with the same simple interface. For example: use `sha256()` to create a SHA-256 hash object. You can now feed this object with bytes-like objects (normally `bytes`) using the `update` method. At any point you can ask it for the digest of the concatenation of the data fed to it so far using the `digest()` or `hexdigest()` methods.

To allow multithreading, the Python GIL is released while computing a hash supplied more than 2047 bytes of data at once in its constructor or `.update` method.

Constructors for hash algorithms that are always present in this module are `sha1()`, `sha224()`, `sha256()`, `sha384()`, `sha512()`, `sha3_224()`, `sha3_256()`, `sha3_384()`, `sha3_512()`, `shake_128()`, `shake_256()`, `blake2b()`, and `blake2s()`. `md5()` is normally available as well, though it may be missing or blocked if you are using a rare «FIPS compliant» build of Python. These correspond to `algorithms_guaranteed`.

Additional algorithms may also be available if your Python distribution’s `hashlib` was linked against a build of OpenSSL that provides others. Others are not guaranteed available on all installations and will only be accessible by name via `new()`. See `algorithms_available`.

Попередження

Some algorithms have known hash collision weaknesses (including MD5 and SHA1). Refer to Attacks on cryptographic hash algorithms and the hashlib-seealso section at the end of this document.

Added in version 3.6: SHA3 (Keccak) and SHAKE constructors `sha3_224()`, `sha3_256()`, `sha3_384()`, `sha3_512()`, `shake_128()`, `shake_256()` were added. `blake2b()` and `blake2s()` were added.

Змінено в версії 3.9: Усі конструктори хешлібів приймають лише ключовий аргумент usedforsecurity зі значенням за замовчуванням `True`. Помилкове значення дозволяє використовувати небезпечні та заблоковані алгоритми хешування в обмежених середовищах. `False` вказує на те, що алгоритм хешування не використовується в контексті безпеки, напр. як некриптографічна функція одностороннього стиснення.

Змінено в версії 3.9: Hashlib now uses SHA3 and SHAKE from OpenSSL if it provides it.

Змінено в версії 3.12: For any of the MD5, SHA1, SHA2, or SHA3 algorithms that the linked OpenSSL does not provide we fall back to a verified implementation from the HACL* project.

Deprecated since version 3.15, will be removed in version 3.19: The undocumented `string` keyword parameter in `_hashlib.new()` and hash-named constructors such as `_md5.md5()` is deprecated. Prefer passing the initial data as a positional argument for maximum backwards compatibility.

## Використання

To obtain the digest of the byte string `b"Nobody inspects the spammish repetition"`:

    >>> import hashlib
    >>> m = hashlib.sha256()
    >>> m.update(b"Nobody inspects")
    >>> m.update(b" the spammish repetition")
    >>> m.digest()
    b'\x03\x1e\xdd}Ae\x15\x93\xc5\xfe\\\x00o\xa5u+7\xfd\xdf\xf7\xbcN\x84:\xa6\xaf\x0c\x95\x0fK\x94\x06'
    >>> m.hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

Більш стисло:

    >>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

## Constructors

hashlib.new(name, [data, ]*, usedforsecurity=True)

  Is a generic constructor that takes the string name of the desired algorithm as its first parameter. It also exists to allow access to the above listed hashes as well as any other algorithms that your OpenSSL library may offer.

Using `new()` with an algorithm name:

    >>> h = hashlib.new('sha256')
    >>> h.update(b"Nobody inspects the spammish repetition")
    >>> h.hexdigest()
    '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'

hashlib.md5([data, ]*, usedforsecurity=True)

hashlib.sha1([data, ]*, usedforsecurity=True)

hashlib.sha224([data, ]*, usedforsecurity=True)

hashlib.sha256([data, ]*, usedforsecurity=True)

hashlib.sha384([data, ]*, usedforsecurity=True)

hashlib.sha512([data, ]*, usedforsecurity=True)

hashlib.sha3_224([data, ]*, usedforsecurity=True)

hashlib.sha3_256([data, ]*, usedforsecurity=True)

hashlib.sha3_384([data, ]*, usedforsecurity=True)

hashlib.sha3_512([data, ]*, usedforsecurity=True)

Named constructors such as these are faster than passing an algorithm name to `new()`.

## Атрибути

Hashlib provides the following constant module attributes:

hashlib.algorithms_guaranteed

  Набір, що містить назви геш-алгоритмів, які гарантовано підтримуватимуться цим модулем на всіх платформах. Зауважте, що «md5» є в цьому списку, незважаючи на те, що деякі постачальники вищого рівня пропонують дивну «FIPS-сумісну» збірку Python, яка виключає його.

  Added in version 3.2.

hashlib.algorithms_available

  Набір, що містить імена геш-алгоритмів, доступних у запущеному інтерпретаторі Python. Ці назви буде розпізнано, коли передано `new()`. `algorithms_guaranteed` завжди буде підмножиною. Той самий алгоритм може з’являтися кілька разів у цьому наборі під різними назвами (завдяки OpenSSL).

  Added in version 3.2.

## Hash Objects

Наступні значення надаються як постійні атрибути хеш-об’єктів, які повертаються конструкторами:

hash.digest_size

  Розмір отриманого хешу в байтах.

hash.block_size

  Розмір внутрішнього блоку хеш-алгоритму в байтах.

Хеш-об’єкт має такі атрибути:

hash.name

  Канонічна назва цього хешу, завжди в нижньому регістрі та завжди підходить як параметр для `new()` для створення іншого хешу цього типу.

  Змінено в версії 3.4: Атрибут name був присутній у CPython з моменту його створення, але до Python 3.4 не було офіційно визначено, тому може не існувати на деяких платформах.

Хеш-об’єкт має такі методи:

hash.update(data)

  Оновіть хеш-об’єкт за допомогою bytes-like object. Повторні виклики еквівалентні одному виклику з конкатенацією всіх аргументів: `m.update(a); m.update(b)` еквівалентно `m.update(a+b)`.

hash.digest()

  Повертає дайджест даних, переданих до цього моменту методу `update()`. Це байтовий об’єкт розміром `digest_size`, який може містити байти в усьому діапазоні від 0 до 255.

hash.hexdigest()

  Подібно до `digest()`, за винятком того, що дайджест повертається як рядковий об’єкт подвійної довжини, що містить лише шістнадцяткові цифри. Це можна використовувати для безпечного обміну значенням в електронній пошті чи в інших небінарних середовищах.

hash.copy()

  Повертає копію («клон») хеш-об’єкта. Це можна використовувати для ефективного обчислення дайджестів даних, які спільно використовують загальний початковий підрядок.

## Дайджести змінної довжини SHAKE

hashlib.shake_128([data, ]*, usedforsecurity=True)

hashlib.shake_256([data, ]*, usedforsecurity=True)

Алгоритми `shake_128()` і `shake_256()` забезпечують дайджести змінної довжини з length_in_bits//2 до 128 або 256 біт безпеки. Таким чином, їх методи дайджесту вимагають довжини. Максимальна довжина не обмежена алгоритмом SHAKE.

shake.digest(length)

  Return the digest of the data passed to the `update()` method so far. This is a bytes object of size length which may contain bytes in the whole range from 0 to 255.

shake.hexdigest(length)

  Like `digest()` except the digest is returned as a string object of double length, containing only hexadecimal digits. This may be used to exchange the value in email or other non-binary environments.

Example use:

    >>> h = hashlib.shake_256(b'Nobody inspects the spammish repetition')
    >>> h.hexdigest(20)
    '44709d6fcb83d92a76dcb0b668c98e1b1d3dafe7'

## File hashing

The hashlib module provides a helper function for efficient hashing of a file or file-like object.

hashlib.file_digest(fileobj, digest, /)

  Return a digest object that has been updated with contents of file object.

  fileobj must be a file-like object opened for reading in binary mode. It accepts file objects from builtin `open()`, `BytesIO` instances, SocketIO objects from `socket.socket.makefile()`, and similar. fileobj must be opened in blocking mode, otherwise a `BlockingIOError` may be raised.

  The function may bypass Python’s I/O and use the file descriptor from `fileno()` directly. fileobj must be assumed to be in an unknown state after this function returns or raises. It is up to the caller to close fileobj.

  digest must either be a hash algorithm name as a str, a hash constructor, or a callable that returns a hash object.

  приклад:

      >>> import io, hashlib, hmac
      >>> with open("library/hashlib.rst", "rb") as f:
      ...     digest = hashlib.file_digest(f, "sha256")
      ...
      >>> digest.hexdigest()
      '...'

      >>> buf = io.BytesIO(b"somedata")
      >>> mac1 = hmac.HMAC(b"key", digestmod=hashlib.sha512)
      >>> digest = hashlib.file_digest(buf, lambda: mac1)

      >>> digest is mac1
      True
      >>> mac2 = hmac.HMAC(b"key", b"somedata", digestmod=hashlib.sha512)
      >>> mac1.digest() == mac2.digest()
      True

  Added in version 3.11.

  Змінено в версії 3.14: Now raises a `BlockingIOError` if the file is opened in blocking mode. Previously, spurious null bytes were added to the digest.

## Виведення ключів

Алгоритми виведення та розтягування ключа створені для безпечного хешування паролів. Наївні алгоритми, такі як `sha1(password)`, не стійкі до атак грубої сили. Хороша функція хешування пароля має бути настроюваною, повільною та містити salt.

hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)

  Ця функція забезпечує функцію виведення ключа на основі пароля PKCS#5 2. Вона використовує HMAC як псевдовипадкову функцію.

  Рядок hash_name є бажаною назвою алгоритму хеш-дайджесту для HMAC, наприклад. «sha1» або «sha256». password і salt інтерпретуються як буфери байтів. Програми та бібліотеки мають обмежувати пароль розумною довжиною (наприклад, 1024). salt має бути приблизно 16 або більше байтів із належного джерела, напр. `os.urandom()`.

  Кількість ітерацій слід вибирати, виходячи з алгоритму хешування та обчислювальної потужності. Станом на 2022 рік пропонуються сотні тисяч ітерацій SHA-256. Для обґрунтування того, чому та як вибрати те, що найкраще підходить для вашої програми, прочитайте Додаток A.2.2 NIST-SP-800-132. Відповіді на stackexchange pbkdf2 iterations question пояснюють детально.

  dklen is the length of the derived key in bytes. If dklen is `None` then the digest size of the hash algorithm hash_name is used, e.g. 64 for SHA-512.

      >>> from hashlib import pbkdf2_hmac
      >>> our_app_iters = 500_000  # Application specific, read above.
      >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt' * 2, our_app_iters)
      >>> dk.hex()
      '15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9'

  Function only available when Python is compiled with OpenSSL.

  Added in version 3.4.

  Змінено в версії 3.12: Function now only available when Python is built with OpenSSL. The slow pure Python implementation has been removed.

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)

  Функція забезпечує функцію виведення ключа на основі пароля scrypt, як визначено в RFC 7914.

  пароль і соль мають бути байтоподібними об’єктами. Програми та бібліотеки повинні обмежувати пароль розумною довжиною (наприклад, 1024). salt має бути приблизно 16 або більше байтів із належного джерела, напр. `os.urandom()`.

  n is the CPU/Memory cost factor, r the block size, p parallelization factor and maxmem limits memory (OpenSSL 1.1.0 defaults to 32 MiB). dklen is the length of the derived key in bytes.

  Added in version 3.6.

## БЛЕЙК2

BLAKE2 — це криптографічна хеш-функція, визначена в RFC 7693, яка має два варіанти:

- BLAKE2b, оптимізований для 64-розрядних платформ і створює дайджести будь-якого розміру від 1 до 64 байтів,

- BLAKE2s, оптимізований для платформ від 8 до 32 біт і створює дайджести будь-якого розміру від 1 до 32 байтів.

BLAKE2 підтримує ключовий режим (швидша та простіша заміна HMAC), солі хешування, персоналізацію та хешування дерева.

Хеш-об’єкти з цього модуля відповідають API об’єктів `hashlib` стандартної бібліотеки.

### Створення хеш-об’єктів

Нові хеш-об’єкти створюються шляхом виклику функцій конструктора:

hashlib.blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)

hashlib.blake2s(data=b'', *, digest_size=32, key=b'', salt=b'', person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, node_depth=0, inner_size=0, last_node=False, usedforsecurity=True)

Ці функції повертають відповідні хеш-об’єкти для обчислення BLAKE2b або BLAKE2s. Вони необов’язково приймають такі загальні параметри:

- data: початкова частина даних для хешування, яка має бути bytes-like object. Його можна передати лише як позиційний аргумент.

- digest_size: розмір вихідного дайджесту в байтах.

- key: ключ для хешування з ключем (до 64 байтів для BLAKE2b, до 32 байтів для BLAKE2s).

- salt: сіль для рандомізованого хешування (до 16 байт для BLAKE2b, до 8 байт для BLAKE2s).

- особа: рядок персоналізації (до 16 байт для BLAKE2b, до 8 байт для BLAKE2s).

У наступній таблиці показано обмеження для загальних параметрів (у байтах):

Хеш | digest_size | len (ключ) | лен (сіль) | len (особа)
--- | --- | --- | --- | ---
BLAKE2b | 64 | 64 | 16 | 16
BLAKE2s | 32 | 32 | 8 | 8

Примітка

Специфікація BLAKE2 визначає постійну довжину параметрів солі та персоналізації, однак для зручності ця реалізація приймає рядки байтів будь-якого розміру до вказаної довжини. Якщо довжина параметра менша за вказану, вона доповнюється нулями, таким чином, наприклад, `b'salt` і `b'salt\x00` є однаковими значеннями. (Це не стосується ключа.)

Ці розміри доступні як constants модуля, описані нижче.

Функції конструктора також приймають такі параметри хешування дерева:

- fanout: розхід (від 0 до 255, 0, якщо необмежений, 1 у послідовному режимі).

- depth: максимальна глибина дерева (від 1 до 255, 255, якщо необмежено, 1 у послідовному режимі).

- leaf_size: максимальна довжина листа в байтах (від 0 до `2**32-1`, 0, якщо необмежений або в послідовному режимі).

- node_offset: зміщення вузла (від 0 до `2**64-1` для BLAKE2b, від 0 до `2**48-1` для BLAKE2s, 0 для першого, крайнього лівого листа, або в послідовному режимі ).

- node_depth: глибина вузла (від 0 до 255, 0 для листів або в послідовному режимі).

- inner_size: розмір внутрішнього дайджесту (від 0 до 64 для BLAKE2b, від 0 до 32 для BLAKE2s, 0 у послідовному режимі).

- last_node: boolean indicating whether the processed node is the last one (`False` for sequential mode).

See section 2.10 in BLAKE2 specification for comprehensive review of tree hashing.

### Константи

blake2b.SALT_SIZE

blake2s.SALT_SIZE

Довжина солі (максимальна довжина, прийнята конструкторами).

blake2b.PERSON_SIZE

blake2s.PERSON_SIZE

Довжина рядка персоналізації (максимальна довжина, прийнята конструкторами).

blake2b.MAX_KEY_SIZE

blake2s.MAX_KEY_SIZE

Максимальний розмір ключа.

blake2b.MAX_DIGEST_SIZE

blake2s.MAX_DIGEST_SIZE

Максимальний розмір дайджесту, який може вивести хеш-функція.

### Приклади

#### Просте хешування

To calculate hash of some data, you should first construct a hash object by calling the appropriate constructor function (`blake2b()` or `blake2s()`), then update it with the data by calling `update()` on the object, and, finally, get the digest out of the object by calling `digest()` (or `hexdigest()` for hex-encoded string).

    >>> from hashlib import blake2b
    >>> h = blake2b()
    >>> h.update(b'Hello world')
    >>> h.hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

Як ярлик, ви можете передати перший фрагмент даних для оновлення безпосередньо в конструктор як позиційний аргумент:

    >>> from hashlib import blake2b
    >>> blake2b(b'Hello world').hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

Ви можете викликати `hash.update()` стільки разів, скільки потрібно для повторного оновлення хешу:

    >>> from hashlib import blake2b
    >>> items = [b'Hello', b' ', b'world']
    >>> h = blake2b()
    >>> for item in items:
    ...     h.update(item)
    ...
    >>> h.hexdigest()
    '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'

#### Використання різних розмірів дайджесту

BLAKE2 має настроюваний розмір дайджестів до 64 байтів для BLAKE2b і до 32 байтів для BLAKE2s. Наприклад, щоб замінити SHA-1 на BLAKE2b без зміни розміру виведення, ми можемо наказати BLAKE2b створювати 20-байтові дайджести:

    >>> from hashlib import blake2b
    >>> h = blake2b(digest_size=20)
    >>> h.update(b'Replacing SHA1 with the more secure function')
    >>> h.hexdigest()
    'd24f26cf8de66472d58d4e1b1774b4c9158b1f4c'
    >>> h.digest_size
    20
    >>> len(h.digest())
    20

Хеш-об’єкти з різними розмірами дайджестів мають абсолютно різні результати (коротші хеші не є префіксами більш довгих хешів); BLAKE2b і BLAKE2s створюють різні результати, навіть якщо довжина виводу однакова:

    >>> from hashlib import blake2b, blake2s
    >>> blake2b(digest_size=10).hexdigest()
    '6fa1d8fcfd719046d762'
    >>> blake2b(digest_size=11).hexdigest()
    'eb6ec15daf9546254f0809'
    >>> blake2s(digest_size=10).hexdigest()
    '1bf21a98c78a1c376ae9'
    >>> blake2s(digest_size=11).hexdigest()
    '567004bf96e4a25773ebf4'

#### Ключове хешування

Хешування з ключем можна використовувати для автентифікації як швидшу та простішу заміну коду автентифікації повідомлення на основі хешу (HMAC). BLAKE2 можна безпечно використовувати в режимі prefix-MAC завдяки властивості індиференційованості, успадкованій від BLAKE.

У цьому прикладі показано, як отримати (в шістнадцятковому кодуванні) 128-бітний код автентифікації для повідомлення `b'message data` з ключем `b'pseudorandom key`:

    >>> from hashlib import blake2b
    >>> h = blake2b(key=b'pseudorandom key', digest_size=16)
    >>> h.update(b'message data')
    >>> h.hexdigest()
    '3d363ff7401e02026f4a4687d4863ced'

Як практичний приклад, веб-додаток може симетрично підписувати файли cookie, надіслані користувачам, а потім перевіряти їх, щоб переконатися, що вони не були змінені:

    >>> from hashlib import blake2b
    >>> from hmac import compare_digest
    >>>
    >>> SECRET_KEY = b'pseudorandomly generated server secret key'
    >>> AUTH_SIZE = 16
    >>>
    >>> def sign(cookie):
    ...     h = blake2b(digest_size=AUTH_SIZE, key=SECRET_KEY)
    ...     h.update(cookie)
    ...     return h.hexdigest().encode('utf-8')
    >>>
    >>> def verify(cookie, sig):
    ...     good_sig = sign(cookie)
    ...     return compare_digest(good_sig, sig)
    >>>
    >>> cookie = b'user-alice'
    >>> sig = sign(cookie)
    >>> print("{0},{1}".format(cookie.decode('utf-8'), sig))
    user-alice,b'43b3c982cf697e0c5ab22172d1ca7421'
    >>> verify(cookie, sig)
    True
    >>> verify(b'user-bob', sig)
    False
    >>> verify(cookie, b'0102030405060708090a0b0c0d0e0f00')
    False

Незважаючи на те, що існує режим хешування з рідним ключем, BLAKE2, звичайно, можна використовувати в конструкції HMAC за допомогою модуля `hmac`:

    >>> import hmac, hashlib
    >>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s)
    >>> m.update(b'message')
    >>> m.hexdigest()
    'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142'

#### Рандомізоване хешування

Установивши параметр salt, користувачі можуть запровадити рандомізацію хеш-функції. Рандомізоване хешування корисне для захисту від колізійних атак на хеш-функцію, яка використовується в цифрових підписах.

> Рандомізоване хешування призначене для ситуацій, коли одна сторона, яка готує повідомлення, створює все або частину повідомлення для підпису другою стороною, особою, яка підписує повідомлення. Якщо готувач повідомлення може знайти колізії криптографічної хеш-функції (тобто два повідомлення, що створюють однакове хеш-значення), тоді він може підготувати значущі версії повідомлення, які створять те саме хеш-значення та цифровий підпис, але з різними результатами (наприклад, , переказуючи на рахунок 1 000 000 доларів США, а не 10 доларів США). Основною метою криптографічних хеш-функцій було розроблено стійкість до зіткнень, але поточна концентрація на атакуючих криптографічних хеш-функціях може призвести до того, що дана криптографічна хеш-функція забезпечить меншу стійкість до зіткнень, ніж очікувалося. Рандомізоване хешування пропонує підписувачу додатковий захист, зменшуючи ймовірність того, що підготовник зможе згенерувати два або більше повідомлень, які в кінцевому підсумку дають однакове хеш-значення під час процесу генерації цифрового підпису — навіть якщо практично знайти колізії для хеш-функції. Однак використання рандомізованого хешування може знизити рівень безпеки, який забезпечує цифровий підпис, коли всі частини повідомлення готуються підписувачем.

> (NIST SP-800-106 «Randomized Hashing for Digital Signatures»)

У BLAKE2 сіль обробляється як одноразовий вхід до хеш-функції під час ініціалізації, а не як вхід для кожної функції стиснення.

Попередження

Salted hashing (or just hashing) with BLAKE2 or any other general-purpose cryptographic hash function, such as SHA-256, is not suitable for hashing passwords. See BLAKE2 FAQ for more information.

    >>> import os
    >>> from hashlib import blake2b
    >>> msg = b'some message'
    >>> # Calculate the first hash with a random salt.
    >>> salt1 = os.urandom(blake2b.SALT_SIZE)
    >>> h1 = blake2b(salt=salt1)
    >>> h1.update(msg)
    >>> # Calculate the second hash with a different random salt.
    >>> salt2 = os.urandom(blake2b.SALT_SIZE)
    >>> h2 = blake2b(salt=salt2)
    >>> h2.update(msg)
    >>> # The digests are different.
    >>> h1.digest() != h2.digest()
    True

#### Персоналізація

Іноді корисно змусити хеш-функцію виробляти різні дайджести для одного введення для різних цілей. Цитую авторів хеш-функції Skein:

> Ми рекомендуємо всім розробникам додатків серйозно подумати про це; ми бачили багато протоколів, де хеш, який обчислюється в одній частині протоколу, може використовуватися в зовсім іншій частині, оскільки два хеш-обчислення були виконані на подібних або пов’язаних даних, і зловмисник може змусити програму зробити вхідні дані хешу те саме. Персоналізація кожної хеш-функції, яка використовується в протоколі, швидко зупиняє цей тип атаки.

> (The Skein Hash Function Family, p. 21)

BLAKE2 можна персоналізувати, передаючи байти в аргумент person:

    >>> from hashlib import blake2b
    >>> FILES_HASH_PERSON = b'MyApp Files Hash'
    >>> BLOCK_HASH_PERSON = b'MyApp Block Hash'
    >>> h = blake2b(digest_size=32, person=FILES_HASH_PERSON)
    >>> h.update(b'the same content')
    >>> h.hexdigest()
    '20d9cd024d4fb086aae819a1432dd2466de12947831b75c5a30cf2676095d3b4'
    >>> h = blake2b(digest_size=32, person=BLOCK_HASH_PERSON)
    >>> h.update(b'the same content')
    >>> h.hexdigest()
    'cf68fb5761b9c44e7878bfb2c4c9aea52264a80b75005e65619778de59f383a3'

Персоналізацію разом із режимом ключа також можна використовувати для отримання різних ключів з одного.

    >>> from hashlib import blake2s
    >>> from base64 import b64decode, b64encode
    >>> orig_key = b64decode(b'Rm5EPJai72qcK3RGBpW3vPNfZy5OZothY+kHY6h21KM=')
    >>> enc_key = blake2s(key=orig_key, person=b'kEncrypt').digest()
    >>> mac_key = blake2s(key=orig_key, person=b'kMAC').digest()
    >>> print(b64encode(enc_key).decode('utf-8'))
    rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw=
    >>> print(b64encode(mac_key).decode('utf-8'))
    G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o=

#### Режим дерева

Ось приклад хешування мінімального дерева з двома листовими вузлами:

      10
     /  \
    00  01

У цьому прикладі використовуються 64-байтові внутрішні дайджести та повертається 32-байтовий остаточний дайджест:

    >>> from hashlib import blake2b
    >>>
    >>> FANOUT = 2
    >>> DEPTH = 2
    >>> LEAF_SIZE = 4096
    >>> INNER_SIZE = 64
    >>>
    >>> buf = bytearray(6000)
    >>>
    >>> # Left leaf
    ... h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=0, node_depth=0, last_node=False)
    >>> # Right leaf
    ... h01 = blake2b(buf[LEAF_SIZE:], fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=1, node_depth=0, last_node=True)
    >>> # Root node
    ... h10 = blake2b(digest_size=32, fanout=FANOUT, depth=DEPTH,
    ...               leaf_size=LEAF_SIZE, inner_size=INNER_SIZE,
    ...               node_offset=0, node_depth=1, last_node=True)
    >>> h10.update(h00.digest())
    >>> h10.update(h01.digest())
    >>> h10.hexdigest()
    '3ad2a9b37c6070e374c7a8c508fe20ca86b6ed54e286e93a0318e95e881db5aa'

### Кредити

BLAKE2 був розроблений Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O’Hearn і Christian Winnerlein на основі фіналіста SHA-3 BLAKE, створеного Jean-Philippe Aumasson, Luca Henzen, Willi Meier і*Raphael C.-W. Phan*.

Він використовує основний алгоритм із шифру ChaCha, розробленого Daniel J. Bernstein.

Реалізація stdlib базується на модулі pyblake2. Його написав Dmitry Chestnykh на основі реалізації C, написаної Samuel Neves. Документація була скопійована з pyblake2 і написана Дмитром Честних.

Код C був частково переписаний для Python Christian Heimes.

Наведені нижче правила загальнодоступного домену застосовуються до реалізації хеш-функції C, коду розширення та цієї документації:

> Наскільки це можливо згідно із законодавством, автор(и) передали всі авторські права, суміжні та суміжні права на це програмне забезпечення у суспільне надбання в усьому світі. Це програмне забезпечення розповсюджується без будь-яких гарантій.

> Ви повинні були отримати копію CC0 Public Domain Dedication разом із цим програмним забезпеченням. Якщо ні, перегляньте https://creativecommons.org/publicdomain/zero/1.0/.

Наступні люди допомогли з розробкою або внесли свої зміни до проекту та суспільного надбання відповідно до Creative Commons Public Domain Dedication 1.0 Universal:

- Олександр Соколовський

Дивись також

Модуль `hmac`

  Модуль для створення кодів автентифікації повідомлень за допомогою хешів.

Модуль `base64`

  Інший спосіб кодування двійкових хешів для небінарних середовищ.

https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.180-4.pdf

  The FIPS 180-4 publication on Secure Hash Algorithms.

https://csrc.nist.gov/pubs/fips/202/final

  The FIPS 202 publication on the SHA-3 Standard.

https://www.blake2.net/

  Офіційний сайт BLAKE2.

https://en.wikipedia.org/wiki/Cryptographic_hash_function

  Стаття у Вікіпедії з інформацією про те, які алгоритми мають відомі проблеми та що це означає щодо їх використання.

https://www.ietf.org/rfc/rfc8018.txt

  PKCS #5: Специфікація криптографії на основі пароля, версія 2.1

https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf

  Рекомендації NIST щодо виведення ключів на основі пароля.