Spec-Zone.ru › Python 3.12

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

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

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

hashlib.algorithms_available

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

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

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

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

hash.digest_size

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

hash.block_size

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

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

hash.name

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

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

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

hash.update(data)

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

Возвращает дайджест данных, переданных методу update() до сих пор. Это объект типа байты размером 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 должен быть либо именем алгоритма хеширования в виде 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

Добавлена в версии 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. Ответы на вопрос о итерациях pbkdf2 на stackexchange подробно объясняют это.

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

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

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

END_OF_DOCUMENT_MARKER

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 определяет постоянные длины для параметров salt и personalization, однако, для удобства, эта реализация принимает байтовые строки любого размера до указанной длины. Если длина параметра меньше указанной, она заполняется нулями, таким образом, например, b'salt' и b'salt\x00' имеют одинаковое значение. (Это не относится к key.)

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

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

  • 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, разработанного Дэниелом Дж. Бернштейном.

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

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

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

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

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

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

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

См. также

Module hmac

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

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

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

END_OF_DOCUMENT_MARKER

Spec-Zone.ru

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