Spec-Zone.ru › Python 3.13

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

Исходный код: Lib/hashlib.py

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

Примечание

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

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

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

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

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

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

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

У некоторых алгоритмов известны уязвимости к коллизиям (включая MD5 и SHA1). Обратитесь к Аттаки на криптографические хэш-алгоритмы и разделу hashlib-seealso в конце этого документа.

Добавлены в версии 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 указывает, что алгоритм хэширования не используется в контексте безопасности, например, как функция некриптографического одностороннего сжатия.

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

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

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

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

Является универсальным конструктором, который принимает строку name желаемого алгоритма в качестве первого параметра. Он также позволяет получить доступ к перечисленным выше хэшам, а также к любым другим алгоритмам, которые может предложить ваша библиотека 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, из которой он исключен.

Добавлен в версии 3.2.

hashlib.algorithms_available

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

Добавлен в версии 3.2.

END_OF_DOCUMENT_MARKER

Объекты хеширования

Следующие значения предоставляются в качестве постоянных атрибутов объектов хеширования, возвращаемых конструкторами:

hash.digest_size

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

hash.block_size

Внутренний размер блока алгоритма хеширования в байтах.

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

hash.name

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

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

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

hash.update(data)

Обновить объект хеширования с помощью объекта типа bytes. Повторные вызовы эквивалентны одному вызову с конкатенацией всех аргументов: 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() предоставляют дайджесты переменной длины с длиной length_in_bits//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, /)

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

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

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

Пример:

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

Добавлен в версии 3.11.

Вычисление ключа

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

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

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

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.

Добавлен в версии 3.4.

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

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

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

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

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

Добавлен в версии 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: начальный фрагмент данных для хеширования, который должен быть байтоподобным объектом. Он может передаваться только как позиционный аргумент.
  • digest_size: размер выходного дайджеста в байтах.
  • key: ключ для хеширования с ключом (до 64 байт для BLAKE2b, до 32 байт для BLAKE2s).
  • salt: соль для случайного хеширования (до 16 байт для BLAKE2b, до 8 байт для BLAKE2s).
  • person: строка персонализации (до 16 байт для BLAKE2b, до 8 байт для BLAKE2s).

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

Хеш

digest_size

len(key)

len(salt)

len(person)

BLAKE2b

64

64

16

16

BLAKE2s

32

32

8

8

Примечание

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

Эти размеры доступны в виде модульных констант, описанных ниже.

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

  • 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 для последовательного режима).
Explanation of tree mode parameters.

См. раздел 2.10 в спецификации BLAKE2 для более подробного обзора хеширования деревьев.

Константы

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'

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

Хэширование с ключом может использоваться для аутентификации в качестве более быстрого и простого заменителя кода аутентификации сообщений на основе хэша (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'

В качестве практического примера веб-приложение может симметрично подписывать куки, отправляемые пользователям, и впоследствии проверять их, чтобы убедиться, что они не были изменены:

>>> 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 «Рандомизированное хэширование для цифровых подписей»)

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

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

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

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

Мы рекомендуем всем разработчикам приложений серьёзно рассмотреть этот вопрос; мы видели много протоколов, в которых хэш, вычисленный в одной части протокола, может использоваться в совершенно другой части, потому что два вычисления хэша были выполнены на похожих или связанных данных, и злоумышленник может заставить приложение сделать входы хэша одинаковыми. Персонализация каждой функции хэширования, используемой в протоколе, суммарно останавливает этот тип атаки.

(Семейство функций хэширования Skein, стр. 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, созданного Жан-Пьером Омассоном, Лукой Хензеном, Вилли Майером и Рафаэлем К.-В. Фаном.

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

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

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

Следующее посвящение общему пользованию применяется как к реализации функции хэширования на языке C, коду расширения, так и к этой документации:

В той мере, в какой это допускается законом, авторы передали все авторские права и смежные права на данное программное обеспечение в общественное достояние во всем мире. Данное программное обеспечение распространяется без каких-либо гарантий.

Вы должны были получить копию посвящения общему пользованию CC0 вместе с данным программным обеспечением. Если нет, обратитесь к https://creativecommons.org/publicdomain/zero/1.0/.

Следующие люди помогали в разработке или внесли свои изменения в проект и общественное достояние в соответствии с универсальным посвящением общественному достоянию Creative Commons 1.0:

  • Александр Соколовский

См. также

Module hmac

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

Module base64

Другой способ кодирования двоичных хэшей для недвоичных сред.

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

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

https://csrc.nist.gov/pubs/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 по производству ключей на основе паролей.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/hashlib.html

END_OF_DOCUMENT_MARKER

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API