hashlib — Защищенные хэши и дайджесты сообщений

Источник: Lib/hashlib.py


Этот модуль реализует общий интерфейс для множества различных безопасных алгоритмов хэширования и дайджеста сообщений. Сюда входят безопасные алгоритмы хэширования SHA1, SHA224, SHA256, SHA384, SHA512 (определены в the FIPS 180-4 standard), серия SHA-3 (определена в the FIPS 202 standard), а также алгоритм MD5 от RSA (определен в интернете RFC 1321). Термины «безопасный хэш» и «дайджест сообщения» взаимозаменяемы. Старые алгоритмы назывались дайджестами сообщений. Современный термин - безопасный хэш.

Примечание

Если вам нужны хэш-функции adler32 или crc32, они доступны в модуле zlib.

Алгоритмы хэширования

Для каждого типа hash существует по одному методу-конструктору. Все они возвращают хэш-объект с одним и тем же простым интерфейсом. Например: используйте sha256() для создания хэш-объекта SHA-256. Теперь вы можете передать этот объект в bytes-like objects (обычно bytes) с помощью метода update. В любой момент вы можете запросить у него digest конкатенацию данных, переданных ему до сих пор, используя методы digest() или hexdigest().

Чтобы обеспечить многопоточность, Python GIL освобождается при вычислении хэша, содержащего более 2047 байт данных одновременно в конструкторе или методе .update.

Конструкторы для хэш-алгоритмов, которые всегда присутствуют в этом модуле, - это sha1(), sha224(), sha256(), sha384(), sha512(), sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256(), blake2b() и blake2s(). md5() обычно также доступен, хотя он может отсутствовать или быть заблокирован, если вы используете редкую «FIPS-совместимую» сборку Python. Они соответствуют algorithms_guaranteed.

Дополнительные алгоритмы также могут быть доступны, если hashlib вашего дистрибутива Python был связан со сборкой OpenSSL, которая предоставляет другие алгоритмы. Другие алгоритмы не гарантированно доступны на всех установках и будут доступны только по имени через new(). См. algorithms_available.

Предупреждение

Некоторые алгоритмы имеют известные недостатки, связанные с хэш-коллизиями (в том числе MD5 и SHA1). См. раздел Attacks on cryptographic hash algorithms и hashlib-seealso в конце этого документа.

Added in version 3.6: Добавлены конструкторы SHA3 (Keccak) и SHAKE sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256(). blake2b() и blake2s().

Изменено в версии 3.9: Все конструкторы hashlib принимают аргумент usedforsecurity со значением по умолчанию True. Значение false позволяет использовать небезопасные и заблокированные алгоритмы хэширования в ограниченных средах. Значение False указывает на то, что алгоритм хэширования не используется в контексте безопасности, например, в качестве некриптографической функции одностороннего сжатия.

Изменено в версии 3.9: Hashlib теперь использует SHA3 и SHAKE из OpenSSL, если он их предоставляет.

Изменено в версии 3.12: Для любого из алгоритмов MD5, SHA1, SHA2 или SHA3, которые не предоставляет связанный OpenSSL, мы возвращаемся к проверенной реализации из HACL* project.

Использование

Чтобы получить дайджест байтовой строки 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'

Конструкторы

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

Это общий конструктор, который принимает в качестве первого параметра строку имя желаемого алгоритма. Он также существует для того, чтобы обеспечить доступ к перечисленным выше хэшам, а также к любым другим алгоритмам, которые может предложить ваша библиотека OpenSSL.

Использование new() с именем алгоритма:

>>> 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)

Такие именованные конструкторы быстрее, чем передача имени алгоритма в new().

Атрибуты

Hashlib предоставляет следующие постоянные атрибуты модуля:

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.digest_size

Размер результирующего хэша в байтах.

hash.block_size

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

Объект хэша имеет следующие атрибуты:

hash.name

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

Изменено в версии 3.4: Атрибут name присутствует в CPython с момента его создания, но до Python 3.4 не был официально определен, поэтому может отсутствовать на некоторых платформах.

Объект hash имеет следующие методы:

hash.update(data)

Обновление хэш-объекта значением bytes-like object. Повторные вызовы эквивалентны одному вызову с конкатенацией всех аргументов: m.update(a); m.update(b) эквивалентен m.update(a+b).

hash.digest()

Возвращает дайджест данных, переданных в метод update() на данный момент. Это объект bytes размера 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() предоставляют дайджесты переменной длины с длиной_в_битах//2 до 128 или 256 бит безопасности. Поэтому для их методов получения дайджеста требуется определенная длина. Максимальная длина не ограничивается алгоритмом SHAKE.

shake.digest(length)

Возвращает дайджест данных, переданных в метод update() на данный момент. Это объект bytes размера length, который может содержать байты во всем диапазоне от 0 до 255.

shake.hexdigest(length)

Как и digest(), за исключением того, что дайджест возвращается в виде строкового объекта двойной длины, содержащего только шестнадцатеричные цифры. Это можно использовать для обмена значениями в электронной почте или других недвоичных средах.

Пример использования:

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

Хеширование файлов

Модуль hashlib предоставляет вспомогательную функцию для эффективного хэширования файла или файлоподобного объекта.

hashlib.file_digest(fileobj, digest, /)

Возвращает объект digest, который был обновлен содержимым объекта file.

fileobj должен быть файлоподобным объектом, открытым для чтения в бинарном режиме. Она принимает файловые объекты из встроенных экземпляров open(), BytesIO, объекты SocketIO из socket.socket.makefile() и подобные. Функция может обойти систему ввода-вывода Python и использовать дескриптор файла из fileno() напрямую. Предполагается, что fileobj находится в неизвестном состоянии после возврата или вызова этой функции. Закрытие fileobj остается за вызывающей стороной.

digest должно быть либо именем хэш-алгоритма в виде str, либо конструктором хэша, либо вызываемым объектом, возвращающим хэш-объект.

Пример:

>>> import io, hashlib, hmac
>>> with open(hashlib.__file__, "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.

Получение ключей

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

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

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

Строка hash_name - это желаемое имя алгоритма хэш-дайджеста для HMAC, например, „sha1“ или „sha256“. password и salt интерпретируются как буферы байтов. Приложения и библиотеки должны ограничивать password разумной длиной (например, 1024). salt должен быть равен 16 или более байтам из подходящего источника, например, os.urandom().

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

dklen - длина производного ключа в байтах. Если dklen равно None, то используется размер дайджеста хэш-алгоритма hash_name, например, 64 для 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'

Функция доступна только в том случае, если Python скомпилирован с OpenSSL.

Added in version 3.4.

Изменено в версии 3.12: Функция теперь доступна только в том случае, если Python собран с OpenSSL. Медленная реализация чистого Python была удалена.

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

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

password и salt должны быть равны bytes-like objects. Приложения и библиотеки должны ограничивать password разумной длиной (например, 1024). salt должен быть равен 16 или более байтам из подходящего источника, например, os.urandom().

n - коэффициент затрат процессора/памяти, r - размер блока, p - коэффициент распараллеливания и maxmem - ограничение памяти (в OpenSSL 1.1.0 по умолчанию установлено значение 32 Мбайт). dklen - длина производного ключа в байтах.

Added in version 3.6.

BLAKE2

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).

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

В следующей таблице приведены ограничения на общие параметры (в байтах):

Хаш

размер_дайджеста

len(key)

len(salt)

len(person)

BLAKE2b

64

64

16

16

BLAKE2s

32

32

8

8

Примечание

Спецификация BLAKE2 определяет постоянную длину для параметров соли и персонализации, однако для удобства данная реализация принимает байтовые строки любого размера вплоть до указанной длины. Если длина параметра меньше указанной, он дополняется нулями, поэтому, например, b'salt' и b'salt\x00' - это одно и то же значение. (Это не относится к key).

Эти размеры доступны в виде модуля constants, описанного ниже.

Функции конструктора также принимают следующие параметры хеширования дерева:

  • fanout: 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: булево число, указывающее, является ли обрабатываемый узел последним (False для последовательного режима).

Объяснение параметров режима дерева.

Полный обзор хеширования деревьев см. в разделе 2.10 в BLAKE2 specification.

Константы

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

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

Примеры

Простое хеширование

Чтобы вычислить хэш некоторых данных, нужно сначала построить хэш-объект, вызвав соответствующую функцию-конструктор (blake2b() или blake2s()), затем обновить его данными, вызвав update(), и, наконец, получить из объекта дайджест, вызвав digest() (или hexdigest() для строки в шестнадцатеричном кодировании).

>>> 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'

Хеширование с ключом

Хеширование с ключом может использоваться для аутентификации как более быстрая и простая замена Hash-based message authentication code (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, пользователь может внести рандомизацию в хэш-функцию. Рандомизированное хэширование полезно для защиты от атак на хэш-функцию, используемую в цифровых подписях.

Случайное хэширование предназначено для ситуаций, когда одна сторона, специалист по подготовке сообщений, генерирует все или часть сообщения, которое должно быть подписано второй стороной, лицом, подписавшим сообщение. Если специалист по подготовке сообщения способен обнаружить коллизии криптографических хэш-функций (т. е. два сообщения, дающие одинаковое хэш-значение), то он может подготовить значимые версии сообщения, которые будут давать одинаковое хэш-значение и цифровую подпись, но с разными результатами (например, перевод на счет не $10, а $1 000 000). Криптографические хэш-функции разрабатывались с учетом устойчивости к столкновениям, однако нынешняя концентрация на атаках на криптографические хэш-функции может привести к тому, что данная криптографическая хэш-функция окажется менее устойчивой к столкновениям, чем ожидалось. Рандомизированное хэширование обеспечивает подписывающему лицу дополнительную защиту, снижая вероятность того, что специалист по подготовке может создать два или более сообщений, которые в конечном итоге дадут одно и то же хэш-значение в процессе генерации цифровой подписи - даже если для хэш-функции практически невозможно найти коллизии. Однако использование рандомизированного хэширования может снизить степень защиты, обеспечиваемую цифровой подписью, когда все части сообщения подготавливаются подписывающим лицом.

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

В BLAKE2 соль обрабатывается как одноразовый вход для хэш-функции во время инициализации, а не как вход для каждой функции сжатия.

Предупреждение

Соленое хэширование (или просто хэширование) с помощью BLAKE2 или любой другой криптографической хэш-функции общего назначения, например SHA-256, не подходит для хэширования паролей. Дополнительную информацию см. в разделе BLAKE2 FAQ.

>>> 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 был разработан Жаном-Филиппом Аумассоном, Самуэлем Невесом, Зуко Вилкоксом-О’Хирном и Кристианом Виннерлейном на основе финалиста SHA-3 BLAKE, созданного Жаном-Филиппом Аумассоном, Лукой Хензеном, Вилли Майером и Рафаэлем К.-В. Phan.

Он использует основной алгоритм из шифра ChaCha, разработанного Даниэлем Дж. Бернштейном.

Реализация stdlib основана на модуле pyblake2. Он был написан Дмитрием Честных на основе реализации на языке C, написанной Самуэлем Невесом. Документация была скопирована из pyblake2 и написана Дмитрием Честных.

Код на языке C был частично переписан для Python Кристианом Хаймсом.

Следующее посвящение общественному достоянию относится как к реализации хэш-функции на языке 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

Публикация FIPS 180-4 о безопасных хэш-алгоритмах.

https://csrc.nist.gov/publications/detail/fips/202/final

Публикация FIPS 202, посвященная стандарту SHA-3.

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 по деривации ключей на основе паролей.