hashlib — 安全散列和消息摘要

源代码: Lib/hashlib.py


此模块实现了一个通用接口,用于访问许多不同的安全散列和消息摘要算法。其中包括 FIPS 安全散列算法 SHA1、SHA224、SHA256、SHA384、SHA512(在 FIPS 180-4 标准中定义)、SHA-3 系列(在 FIPS 202 标准中定义)以及 RSA 的 MD5 算法(在互联网 RFC 1321 中定义)。术语“安全散列”和“消息摘要”可以互换使用。较旧的算法称为消息摘要。现代术语是安全散列。

备注

如果您需要 adler32 或 crc32 哈希函数,它们可以在 zlib 模块中使用。

哈希算法

每种类型的哈希都有一个构造方法。所有这些方法都返回一个具有相同简单接口的哈希对象。例如:使用 sha256() 创建一个 SHA-256 哈希对象。您现在可以使用 update 方法,将类字节对象(通常是 bytes)馈送到此对象。在任何时候,您都可以使用 digest()hexdigest() 方法,请求它返回到目前为止所馈送数据的摘要

为了允许多线程,当哈希在其构造函数或 .update 方法中一次接收超过 2047 字节的数据时,Python GIL 将被释放。

此模块中始终存在的哈希算法的构造函数有 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 发行版的 hashlib 是链接到提供其他算法的 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 值允许在受限环境中使用不安全和被阻止的哈希算法。False 表示哈希算法不用于安全上下文,例如用作非加密单向压缩函数。

在 3.9 版本中更改: 如果 Hashlib 现在使用 OpenSSL 提供的 SHA3 和 SHAKE。

在 3.12 版本中更改: 对于链接的 OpenSSL 未提供的任何 MD5、SHA1、SHA2 或 SHA3 算法,我们会回退到 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”的奇怪的“符合 FIPS 标准”的 Python 版本,但“md5”在此列表中。

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 实例,来自 socket.socket.makefile() 的 SocketIO 对象以及类似对象的文件对象。该函数可能会绕过 Python 的 I/O 并直接使用来自 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 迭代。有关为什么以及如何选择最适合你的应用程序的理由,请阅读 NIST-SP-800-132 的*附录 A.2.2*。 stackexchange pbkdf2 迭代问题上的解答详细解释了这一点。

dklen 是派生密钥的长度(以字节为单位)。如果 *dklen* 是 None,则使用哈希算法 *hash_name* 的摘要大小,例如 SHA-512 为 64。

>>> 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 是 CPU/内存成本因子,*r* 是块大小,*p* 是并行化因子,而 *maxmem* 限制内存(OpenSSL 1.1.0 默认为 32 MiB)。 *dklen* 是派生密钥的长度(以字节为单位)。

3.6 版本新增。

BLAKE2

BLAKE2 是在 RFC 7693 中定义的加密哈希函数,它有两种风格

  • BLAKE2b,针对 64 位平台优化,并生成 1 到 64 字节之间的任意大小的摘要,

  • BLAKE2s,针对 8 位到 32 位平台优化,并生成 1 到 32 字节之间的任意大小的摘要。

BLAKE2 支持键控模式HMAC 的更快、更简单的替代方案)、加盐哈希个性化树哈希

此模块中的哈希对象遵循标准库的 hashlib 对象的 API。

创建哈希对象

通过调用构造函数创建新的哈希对象

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: 用于密钥哈希的密钥(BLAKE2b 最大 64 字节,BLAKE2s 最大 32 字节)。

  • salt: 用于随机哈希的盐值(BLAKE2b 最大 16 字节,BLAKE2s 最大 8 字节)。

  • person: 个性化字符串(BLAKE2b 最大 16 字节,BLAKE2s 最大 8 字节)。

下表显示了通用参数的限制(以字节为单位)

哈希

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: 扇出(0 到 255,无限制时为 0,顺序模式下为 1)。

  • depth: 树的最大深度(1 到 255,无限制时为 255,顺序模式下为 1)。

  • leaf_size: 叶的最大字节长度(0 到 2**32-1,无限制或顺序模式下为 0)。

  • node_offset: 节点偏移量(BLAKE2b 为 0 到 2**64-1,BLAKE2s 为 0 到 2**48-1,第一个、最左边的叶子或顺序模式下为 0)。

  • node_depth: 节点深度(0 到 255,叶子或顺序模式下为 0)。

  • inner_size: 内部摘要大小(BLAKE2b 为 0 到 64,BLAKE2s 为 0 到 32,顺序模式下为 0)。

  • last_node: 布尔值,指示处理的节点是否为最后一个节点(顺序模式下为False)。

Explanation of tree mode parameters.

有关树哈希的全面审查,请参阅BLAKE2 规范中的 2.10 节。

常量

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 的摘要大小是可配置的,BLAKE2b 最大为 64 字节,BLAKE2s 最大为 32 字节。例如,要将 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) 的更快更简单的替代方案。由于 BLAKE 继承的不可区分性属性,BLAKE2 可以安全地用于前缀 MAC 模式。

此示例展示了如何使用密钥b'pseudorandom key'获取消息b'message data'的 128 位身份验证码(十六进制编码)

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

作为一个实际示例,Web 应用程序可以对称地对发送给用户的 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 “数字签名的随机哈希”)

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

可以通过将字节传递给 *person* 参数来个性化 BLAKE2

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

鸣谢

BLAKE2Jean-Philippe AumassonSamuel NevesZooko Wilcox-O’HearnChristian Winnerlein 基于 SHA-3 决赛入围者 BLAKE 设计,后者由 Jean-Philippe AumassonLuca HenzenWilli MeierRaphael C.-W. Phan 创建。

它使用由 Daniel J. Bernstein 设计的 ChaCha 密码的核心算法。

stdlib 实现基于 pyblake2 模块。它由 Dmitry Chestnykh 基于 Samuel Neves 编写的 C 实现编写。文档从 pyblake2 复制,并由 Dmitry Chestnykh 编写。

C 代码部分由 Christian Heimes 为 Python 重写。

以下公共领域贡献适用于 C 哈希函数实现、扩展代码和本文档

在法律允许的最大范围内,作者已将其所有版权和相关及邻近权利贡献给本软件,供全世界公共领域使用。本软件的发布不提供任何保证。

您应该已经收到与本软件一起提供的 CC0 公共领域贡献的副本。如果未收到,请参阅 https://creativecommons.org/publicdomain/zero/1.0/

以下人员帮助开发或根据知识共享公共领域贡献 1.0 通用版将他们的更改贡献到项目和公共领域

  • Alexandr Sokolovskiy

另请参阅

模块 hmac

一个使用哈希生成消息身份验证代码的模块。

模块 base64

另一种为非二进制环境编码二进制哈希的方法。

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

关于安全哈希算法的 FIPS 180-4 出版物。

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

关于 SHA-3 标准的 FIPS 202 出版物。

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 关于基于密码的密钥派生的建议。