​hashlib --- 安全哈希与消息摘要​

news2024/7/2 4:27:00

源码: Lib/hashlib.py


本模块针对许多不同的安全哈希和消息摘要算法实现了一个通用接口。 包括了 FIPS 安全哈希算法 SHA1, SHA224, SHA256, SHA384, SHA512, (定义见 the FIPS 180-4 standard), SHA-3 系列 (定义见 the FIPS 202 standard) 以及 RSA 的 MD5 算法 (定义见互联网 RFC 1321)。 术语 "安全哈希" 和 "消息摘要" 是同义的。 较旧的算法被称为消息摘要。 现代的术语则是安全哈希。

备注

如果你想找到 adler32 或 crc32 哈希函数,它们在 zlib 模块中。

哈希算法

每种类型的 hash 都有一个构造器方法。 它们都返回一个具有相同简单接口的哈希对象。 例如,使用 sha256() 创建一个 SHA-256 哈希对象。 你可以使用 update 方法向这个对象输入 字节类对象 (通常是 bytes)。 在任何时候你都可以使用 digest() 或 hexdigest() 方法获得到目前为止输入这个对象的拼接数据的 digest

为了允许多线程,当在其构造器或 .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)。 请参阅本文档末尾的 Attacks on cryptographic hash algorithms 和 hashlib-seealso 小节。

3.6 新版功能: 增加了 SHA3 (Keccak) 和 SHAKE 构造器 sha3_224(), sha3_256(), sha3_384(), sha3_512(), shake_128(), shake_256()。

3.6 新版功能: 添加了 blake2b() 和 blake2s() 。

在 3.9 版更改: 所有 hashlib 的构造器都接受仅限关键字参数 usedforsecurity 且其默认值为 True。 设为假值即允许在受限的环境中使用不安全且阻塞的哈希算法。 False 表示此哈希算法不可用于安全场景,例如用作非加密的单向压缩函数。

在 3.9 版更改: 现在 hashlib 会在 OpenSSL 有提供的情况下使用 SHA3 和 SHAKE。

在 3.12 版更改: 在所链接的 OpenSSL 未提供 MD5, SHA1, SHA2 或 SHA3 算法的情况下我们将回退至来自 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)

接受想要的算法对应的字符串 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 新版功能.

哈希对象

下列值会以构造器所返回的哈希对象的常量属性的形式被提供:

hash.digest_size

以字节表示的结果哈希对象的大小。

hash.block_size

以字节表示的哈希算法的内部块大小。

hash 对象具有以下属性:

hash.name

此哈希对象的规范名称,总是为小写形式并且总是可以作为 new() 的形参用来创建另一个此类型的哈希对象。

在 3.4 版更改: 该属性名称自被引入起即存在于 CPython 中,但在 Python 3.4 之前并未正式指明,因此可能不存在于某些平台上。

哈希对象具有下列方法:

hash.update(data)

用 bytes-like object 来更新哈希对象。 重复调用相当于单次调用并传入所有参数的拼接结果: m.update(a); m.update(b) 等价于 m.update(a+b)

hash.digest()

返回当前已传给 update() 方法的数据摘要。 这是一个大小为 digest_size 的字节串对象,字节串中可包含 0 至 255 的完整取值范围。

hash.hexdigest()

类似于 digest() 但摘要会以两倍长度字符串对象的形式返回,其中仅包含十六进制数码。 这可以被用于在电子邮件或其他非二进制环境中安全地交换数据值。

hash.copy()

返回哈希对象的副本(“克隆”)。 这可被用来高效地计算共享相同初始子串的数据的摘要。

SHAKE 可变长度摘要

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

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

shake_128() 和 shake_256() 算法提供安全的 length_in_bits//2 至 128 或 256 位可变长度摘要。 为此,它们的摘要需指定一个长度。 SHAKE 算法不限制最大长度。

shake.digest(length)

返回当前已传给 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(fileobjdigest/)

返回一个根据文件对象进行更新的摘要对象。

fileobj 必须是一个以二进制模式打开用于读取的文件类对象。 它接受来自内置 open(), BytesIO 实例, socket.socket.makefile() 创建的 SocketIO 及其他类似的文件对象。 此函数也可能绕过 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_namepasswordsaltiterationsdklen=None)

此函数提供 PKCS#5 基于密码的密钥派生函数 2。 它使用 HMAC 作为伪随机函数。

字符串 hash_name 是要求用于 HMAC 的哈希摘要算法的名称,例如 'sha1' 或 'sha256'。 password 和 salt 会以字节串缓冲区的形式被解析。 应用和库应当将 password 限制在合理长度 (例如 1024)。 salt 应当为适当来源例如 os.urandom() 的大约 16 个或更多的字节串数据。

iterations 的数值应当基于哈希算法和机器算力来选择。 在 2022 年,建议选择进行数万次的 SHA-256 迭代。 对于为何以及如何选择最适合你的应用程序的迭代次数的理由,请参阅 NIST-SP-800-132 的 Appendix 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*saltnrpmaxmem=0dklen=64)

此函数提供基于密码加密的密钥派生函数,其定义参见 RFC 7914。

password 和 salt 必须为 字节类对象。 应用和库应当将 password 限制在合理长度 (例如 1024)。 salt 应当为适当来源例如 os.urandom() 的大约 16 个或更多的字节串数据。

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 支持 keyed mode (HMAC 的更快速更简单的替代), salted hashingpersonalization 和 tree hashing.

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

创建哈希对象

新哈希对象可通过调用构造器函数来创建:

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

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

这些函数返回用于计算 BLAKE2b 或 BLAKE2s 的相应的哈希对象。 它们接受下列可选通用形参:

  • data: 要哈希的初始数据块,它必须为 bytes-like object。 它只能作为位置参数传入。

  • digest_size: 以字节数表示的输出摘要大小。

  • key: 用于密钥哈希的密钥(对于 BLAKE2b 最长 64 字节,对于 BLAKE2s 最长 32 字节)。

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

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

下表显示了常规参数的限制(以字节为单位):

Hash

目标长度

长度(键)

长度(盐)

长度(个人)

BLAKE2b

64

64

16

16

BLAKE2s

32

32

8

8

备注

BLAKE2 规格描述为盐值和个性化形参定义了固定的长度,但是为了方便起见,此实现接受指定在长度以内的任意大小的字节串。 如果形参长度小于指定值,它将以零值进行填充,因此举例来说,b'salt' 和 b'salt\x00' 为相同的值 (key 的情况则并非如此。)

如下面的模块 constants 所描述,这些是可用的大小取值。

构造器函数还接受下列树形哈希形参:

  • 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) 的布尔值。

树模式形参的说明。

请参阅 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 字节。 例如,要使用 BLAKE2b 来替代 SHA-1 而不改变输出大小,我们可以让 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 可被安全地用于前缀 MAC 模式,这是由于它从 BLAKE 继承而来的不可区分特性。

这个例子演示了如何使用密钥 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 应用可为发送给用户的 cookies 进行对称签名,并在之后对其进行验证以确保它们没有被篡改:

>>>

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

即使存在原生的密钥哈希模式,BLAKE2 也同样可在 hmac 模块的 HMAC 构造过程中使用:

>>>

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

用户可通过设置 salt 形参来为哈希函数引入随机化。 随机哈希适用于防止对数字签名中使用的哈希函数进行碰撞攻击。

随机哈希被设计用来处理当一方(消息准备者)要生成由另一方(消息签名者)进行签名的全部或部分消息的情况。 如果消息准备者能够找到加密哈希函数的碰撞现象(即两条消息产生相同的哈希值),则他们就可以准备将产生相同哈希值和数字签名但却具有不同结果的有意义的消息版本(例如向某个账户转入 $1,000,000 而不是 $10)。 加密哈希函数的设计都是以防碰撞性能为其主要目标之一的,但是当前针对加密哈希函数的集中攻击可能导致特定加密哈希函数所提供的防碰撞性能低于预期。 随机哈希为签名者提供了额外的保护,可以降低准备者在数字签名生成过程中使得两条或更多条消息最终产生相同哈希值的可能性 --- 即使为特定哈希函数找到碰撞现象是可行的。 但是,当消息的所有部分均由签名者准备时,使用随机哈希可能降低数字签名所提供的安全性。

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

在 BLAKE2 中,盐值会在初始化期间作为对哈希函数的一次性输入而不是对每个压缩函数的输入来处理。

警告

使用 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 哈希函数的作者所言:

我们建议所有应用设计者慎重考虑这种做法;我们已看到有许多协议在协议的某一部分中计算出来的哈希值在另一个完全不同的部分中也可以被使用,因为两次哈希计算是针对类似或相关的数据进行的,这样攻击者可以强制应用为相同的输入生成哈希值。 个性化协议中所使用的每个哈希函数将有效地阻止这种类型的攻击。

(Skein 哈希函数族, p. 21)

BLAKE2 可通过向 person 参数传入字节串来进行个性化:

>>>

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

个性化配合密钥模式也可被用来从单个密钥派生出多个不同密钥。

>>>

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

以下是对包含两个叶子节点的最小树进行哈希的例子:

  10
 /  \
00  01

这个例子使用 64 字节内部摘要,返回 32 字节最终摘要:

>>>

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

开发人员

BLAKE2 是由 Jean-Philippe AumassonSamuel NevesZooko Wilcox-O'Hearn 和 Christian Winnerlein 基于 Jean-Philippe AumassonLuca HenzenWilli Meier 和 Raphael C.-W. Phan 所创造的 SHA-3 入围方案 BLAKE 进行设计的。

它使用的核心算法来自由 Daniel J. Bernstein 所设计的 ChaCha 加密。

stdlib 实现是基于 pyblake2 模块的。 它由 Dmitry Chestnykh 在 Samuel Neves 所编写的 C 实现的基础上编写。 此文档拷贝自 pyblake2 并由 Dmitry Chestnykh 撰写。

C 代码由 Christian Heimes 针对 Python 进行了部分的重写。

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

在法律许可的范围内,作者已将此软件的全部版权以及关联和邻接权利贡献到全球公共领域。 此软件的发布不附带任何担保。

你应该已收到此软件附带的 CC0 公共领域专属证书的副本。 如果没有,请参阅 CC0 1.0 Deed | CC0 1.0 Universal | Creative Commons。

根据创意分享公共领域贡献 1.0 通用规范,下列人士为此项目的开发提供了帮助或对公共领域的修改作出了贡献:

  • Alexandr Sokolovskiy

参见

模块 hmac

使用哈希运算来生成消息验证代码的模块。

模块 base64

针对非二进制环境对二进制哈希值进行编辑的另一种方式。

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

有关安全哈希算法的 FIPS 180-4 发布版。

FIPS 202, SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions | CSRC

关于 SHA-3 标准的 FIPS 202 公告。

BLAKE2

BLAKE2 官方网站

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

包含关于哪些算法存在已知问题以及对其使用所造成的影响的信息的 Wikipedia 文章。

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

PKCS #5: 基于密码的加密规范描述 2.1 版

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

NIST 对基于密码的密钥派生的建议。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1306517.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HarmonyOS首次尝试-HelloWorld

我的旧手机是个HUAWEI PCT-AL10 HarmonyOS 3.0.0(Android 10) 插上后,studio能显示连接上了手机设备,创建的demo使用的是API9,也就是当前的最新版本。 点击运行报错: 点击去往帮助页,做的也挺好,有直达的…

OpenAI 承认 ChatGPT 最近确实变懒,承诺修复问题

文章目录 一. ChatGPT 指令遵循能力下降引发用户投诉1.1 用户抱怨回应速度慢、敷衍回答、拒绝回答和中断会话 二. OpenAI 官方确认 ChatGPT 存在问题,展开调查三. OpenAI 解释模型行为差异,回应用户质疑四. GPT-4 模型变更受人事动荡和延期影响 一. Chat…

电子学会C/C++编程等级考试2022年09月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:城堡问题 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # | # # # # # #---#####---#####---#####---# 3 # | | # # # # # #---#########---#####---#---# 4 # # | | | …

30、Linux安全配置

文章目录 一、Linux安全配置简介二、Linux安全配置2.1 网络配置2.2 防火墙配置2.2.1 确定防火墙区域配置 2.3 日志和审核2.4 访问、认证和授权2.4.1 SSH配置2.4.2 PAM模块配置 一、Linux安全配置简介 Linux种类较多,常用的有Redhat、Ubantu、Centos等。这里以Cento…

本地项目通过Gitee上传代码码云仓库(保姆级教程)

前提 1.已经下载过Git Bash Git bash安装包教程 2.在Gitee上创建该项目的远程仓库 3.进入本地你想要上传的文件目录下,右键单击空白处,点击Git Bash Here 4.配置你邮箱和email 邮箱在设置可以看到 ----- 用户名可用在个人主页admin 下面那个就是用户…

C语言:高精度乘法

P1303 A*B Problem - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 第一次画图&#xff0c;略显简陋。 由图可以看出c的小标与x,y下标的关系为x的下标加上y的下标再减一。 由此得到&#xff1a; c [ i j - 1 ] x [ i ] * y [ j ]x #include<stdio.h> #include<st…

第二证券:如何申购新股?

跟着科技的展开&#xff0c;股市的展开也变得越来越快速。在股市上&#xff0c;申购新股是许多出资者寻求短期利润的一种方法。但是&#xff0c;申购新股并不是简略的作业。那么&#xff0c;在申购新股时&#xff0c;有哪些问题需求咱们重视呢&#xff1f;在本文中&#xff0c;…

重要功能更新:妙手ERP上线物流追踪功能,全方位助力跨境卖家轻松掌握包裹动态!

由于跨境物流转运环节多&#xff0c;历程耗时长&#xff0c;途中不可控因素多&#xff0c;容易导致包裹状态异常&#xff0c;从而引起买家客诉&#xff0c;造成卖家运营损失。因而&#xff0c;可随时查看物流信息、掌握包裹动态&#xff0c;是跨境运营中至关重要的一环。 为此…

在windows11上彻底关闭系统更新

最近在windows11系统上发现网上的一些方法不太有效&#xff0c;系统还是会自己更新。像该注册表&#xff0c;计划任务等这些&#xff0c;在windows11上都不太行。下面介绍一个在windows11上有效的方法&#xff0c;先看看效果图吧。如下&#xff1a; 在最新windows11上面 在较新…

一览汽配CRM系统的价格与功能:企业决策者的指南

随着汽车行业的快速发展&#xff0c;汽车配件市场也呈现出蓬勃的增长态势。然而&#xff0c;随之而来的是市场竞争的加剧和管理难题的增多。为了应对这些挑战&#xff0c;汽配行业也引入了CRM客户管理系统。本文将简要向您介绍&#xff0c;汽配CRM是什么&#xff0c;有什么功能…

【教程】Ipa Guard为iOS应用提供免费加密混淆方案

概述&#xff1a;使用ios加固工具对ios代码保护&#xff0c;保护ios项目中的核心代码&#xff0c; #ipagurd年终大促百厂联动暖冬特惠&#xff0c;超多软控件立享惊喜优惠>> ​ 简介 iOS加固保护是直接针对ios ipa二进制文件的保护技术&#xff0c;可以对iOS APP中的可…

9:00面试,9:05就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到12月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40…

关键点检测☞png格式换bmp,且labelme标注的json中imagePath同步修改格式

import os import cv2 import jsondef bmp2jpg(in_img_path, out_dir_name): # .png -> .bmp# img = cv2.imread(in_img_path) # 彩色图片,位深24img =</

125. LCR图书整理 II

LCR 125. 图书整理 II 题目&#xff1a; 读者来到图书馆排队借还书&#xff0c;图书管理员使用两个书车来完成整理借还书的任务。书车中的书从下往上叠加存放&#xff0c;图书管理员每次只能拿取书车顶部的书。排队的读者会有两种操作&#xff1a; push(bookID)&#xff1a;…

web279(s2-001)

目前java小白一个&#xff0c;主要是学学别人的思路 进入题目&#xff0c;登录框一个 抓包也没发现什么东西 网上说是struts2框架 Struts2是用Java语言编写的一个基于MVC设计模式的Web应用框架 判断是不是基于struts2的一些方法&#xff1a; 1.通过页面回显的错误消息来判断…

Python从入门到精通八:Python文件操作

文件的编码 思考&#xff1a;计算机只能识别&#xff1a;0和1&#xff0c;那么我们丰富的文本文件是如何被计算机识别&#xff0c;并存储在硬盘中呢&#xff1f; 答案&#xff1a;使用编码技术&#xff08;密码本&#xff09;将内容翻译成0和1存入。 编码技术即&#xff1a;…

十九)Stable Diffusion使用教程:ai室内设计案例

今天我们聊聊如何通过SD进行室内设计装修。 基础起手式&#xff1a; 选择常用算法&#xff0c;抽卡&#xff1a; 这里要安装一个插件&#xff0c;latent couple&#xff08;潜变量成对&#xff09;&#xff1a; 安装地址如下&#xff1a; GitHub - ashen-sensored/stable-diff…

Java调用百度翻译API和调用有道翻译API进行翻译

目录 界面编写 调用百度API 调用有道API 源代码 界面编写 我们首先需要设计出这个翻译程序的GUI界面&#xff0c;我们写一个类继承自JFrame类&#xff0c;用来展示程序的主窗口&#xff0c;设置好窗口的名称和大小&#xff0c;设置在关闭窗口时终止程序&#xff0c;为了界…

【UE】在蓝图中修改材质实例的参数的两种方式

目录 方式一、通过“在材质上设置标量/向量参数值”节点实现 方式二、通过“设置标量/向量参数值”节点实现 方式一、通过“在材质上设置标量/向量参数值”节点实现 1. 在材质中设置了两个参数 2. 创建材质实例 3. 创建一个蓝图&#xff0c;对静态网格体赋予材质实例 在事件…