hashlib
— Secure hashes and message digests安全哈希和消息摘要¶
Source code: Lib/hashlib.py
This module implements a common interface to many different secure hash and message digest algorithms. 该模块实现了许多不同安全哈希和消息摘要算法的通用接口。Included are the FIPS secure hash algorithms SHA1, SHA224, SHA256, SHA384, and SHA512 (defined in FIPS 180-2) as well as RSA’s MD5 algorithm (defined in internet RFC 1321). 包括FIPS安全哈希算法SHA1、SHA224、SHA256、SHA384和SHA512(在FIPS 180-2中定义)以及RSA的MD5算法(在互联网RFC 1321中定义)。The terms “secure hash” and “message digest” are interchangeable. 术语“安全哈希”和“消息摘要”可以互换。Older algorithms were called message digests. 旧的算法称为消息摘要。The modern term is secure hash.现代术语是安全散列。
Note
If you want the adler32 or crc32 hash functions, they are available in the 如果需要adler32或crc32哈希函数,可以在zlib
module.zlib
模块中使用。
Warning警告
Some algorithms have known hash collision weaknesses, refer to the “See also” section at the end.一些算法已知哈希冲突弱点,请参阅最后的“另请参阅”部分。
Hash algorithms散列算法¶
There is one constructor method named for each type of hash. 每种类型的散列都有一个构造函数方法。All return a hash object with the same simple interface. 都返回具有相同简单接口的哈希对象。For example: use 例如:使用sha256()
to create a SHA-256 hash object. sha256()
创建SHA-256哈希对象。You can now feed this object with bytes-like objects (normally 现在可以使用bytes
) using the update()
method. update()
方法向该对象提供类似字节的对象(通常是bytes
)。At any point you can ask it for the digest of the concatenation of the data fed to it so far using the 在任何时候,您都可以使用digest()
or hexdigest()
methods.digest()
或hexdigest()
方法要求它提供到目前为止提供给它的数据连接的摘要。
Note
For better multithreading performance, the Python GIL is released for data larger than 2047 bytes at object creation or on update.为了获得更好的多线程性能,Python GIL在对象创建或更新时针对大于2047字节的数据发布。
Note
Feeding string objects into 不支持将字符串对象馈送到update()
is not supported, as hashes work on bytes, not on characters.update()
中,因为散列处理的是字节,而不是字符。
Constructors for hash algorithms that are always present in this module are 此模块中始终存在的哈希算法的构造函数是sha1()
, sha224()
, sha256()
, sha384()
, sha512()
, blake2b()
, and blake2s()
. sha1()
、sha224()
、sha256()
、sha384()
、sha512()
、blake2b()
和blake2s()
。md5()
is normally available as well, though it may be missing or blocked if you are using a rare “FIPS compliant” build of Python. md5()
通常也可用,但如果您使用的是罕见的“符合FIPS的”Python版本,它可能会丢失或被阻止。Additional algorithms may also be available depending upon the OpenSSL library that Python uses on your platform. 根据Python在您的平台上使用的OpenSSL库,还可能提供其他算法。On most platforms the 在大多数平台上,sha3_224()
, sha3_256()
, sha3_384()
, sha3_512()
, shake_128()
, shake_256()
are also available.sha3_224()
、sha3_256()
、sha3_384()
、sha3_512()
、shake_128()
。
New in version 3.6.版本3.6中新增。SHA3 (Keccak) and SHAKE constructors SHA3(Keccak)和SHAKE构造sha3_224()
, sha3_256()
, sha3_384()
, sha3_512()
, shake_128()
, shake_256()
.sha3_224()
、sha3_256()
、 sha3_384()
、sha3_512()
、shake_128()
、shake_256()
。
Changed in version 3.9:版本3.9中更改: All hashlib constructors take a keyword-only argument usedforsecuritywith default value 所有hashlib构造函数都使用一个仅关键字参数usedforsecurity,默认值为True
. True
。A false value allows the use of insecure and blocked hashing algorithms in restricted environments. 假值允许在受限环境中使用不安全和阻塞的哈希算法。False
indicates that the hashing algorithm is not used in a security context, e.g. as a non-cryptographic one-way compression function.False
表示哈希算法未在安全上下文中使用,例如作为非加密单向压缩函数。
Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer.Hashlib现在使用OpenSSL 1.1.1及更新版本中的SHA3和SHAKE。
For example, to obtain the digest of the byte string 例如,为了获得字节字符串b'Nobody inspects the spammish repetition'
: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.digest_size
32
>>> m.block_size
64
More condensed:更浓缩的:
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
-
hashlib.
new
(name, [data, ]*, usedforsecurity=True)¶ Is a generic constructor that takes the string name of the desired algorithm as its first parameter.是一个通用构造函数,它将所需算法的字符串名称作为其第一个参数。It also exists to allow access to the above listed hashes as well as any other algorithms that your OpenSSL library may offer.它还允许访问上面列出的哈希以及OpenSSL库可能提供的任何其他算法。The named constructors are much faster than命名构造函数比new()
and should be preferred.new()
快得多,应该是首选。
Using 使用new()
with an algorithm provided by OpenSSL:new()
和OpenSSL提供的算法:
>>> h = hashlib.new('sha256')
>>> h.update(b"Nobody inspects the spammish repetition")
>>> h.hexdigest()
'031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406'
Hashlib provides the following constant attributes:Hashlib提供以下常量属性:
-
hashlib.
algorithms_guaranteed
¶ A set containing the names of the hash algorithms guaranteed to be supported by this module on all platforms.一个包含哈希算法名称的集合,保证该模块在所有平台上都支持。Note that ‘md5’ is in this list despite some upstream vendors offering an odd “FIPS compliant” Python build that excludes it.请注意,“md5”在这个列表中,尽管一些上游供应商提供了一个奇怪的“符合FIPS的”Python构建,但将其排除在外。New in version 3.2.版本3.2中新增。
-
hashlib.
algorithms_available
¶ A set containing the names of the hash algorithms that are available in the running Python interpreter.包含在运行的Python解释器中可用的哈希算法名称的集合。These names will be recognized when passed to这些名称在传递给new()
.new()
时将被识别。algorithms_guaranteed
will always be a subset.将始终是子集。The same algorithm may appear multiple times in this set under different names (thanks to OpenSSL).同一算法可能会以不同的名称多次出现在该集中(多亏了OpenSSL)。New in version 3.2.版本3.2中新增。
The following values are provided as constant attributes of the hash objects returned by the constructors:以下值作为构造函数返回的哈希对象的常量属性提供:
-
hash.
digest_size
¶ The size of the resulting hash in bytes.结果哈希的大小(字节)。
-
hash.
block_size
¶ The internal block size of the hash algorithm in bytes.哈希算法的内部块大小(字节)。
A hash object has the following attributes:哈希对象具有以下属性:
-
hash.
name
¶ The canonical name of this hash, always lowercase and always suitable as a parameter to此哈希的规范名称,始终小写,并且始终适合作为new()
to create another hash of this type.new()
的参数,以创建此类型的另一个哈希。Changed in version 3.4:版本3.4中更改:The name attribute has been present in CPython since its inception, but until Python 3.4 was not formally specified, so may not exist on some platforms.自CPython创建以来,name属性就一直存在于它中,但直到Python 3.4没有正式指定,因此在某些平台上可能不存在。
A hash object has the following methods:哈希对象具有以下方法:
-
hash.
update
(data)¶ Update the hash object with the bytes-like object.用类字节对象更新哈希对象。Repeated calls are equivalent to a single call with the concatenation of all the arguments:重复调用等同于所有参数串联的单个调用:m.update(a); m.update(b)
is equivalent tom.update(a+b)
.m.update(a); m.update(b)
等同于m.update(a+b)
。Changed in version 3.1:版本3.1中更改:The Python GIL is released to allow other threads to run while hash updates on data larger than 2047 bytes is taking place when using hash algorithms supplied by OpenSSL.当使用OpenSSL提供的哈希算法时,发布Python GIL允许其他线程在对大于2047字节的数据进行哈希更新时运行。
-
hash.
digest
()¶ Return the digest of the data passed to the返回到目前为止传递给update()
method so far.update()
方法的数据摘要。This is a bytes object of size这是一个大小为digest_size
which may contain bytes in the whole range from 0 to 255.digest_size
的字节对象,它可以包含从0到255的整个范围内的字节。
-
hash.
hexdigest
()¶ Like与digest()
except the digest is returned as a string object of double length, containing only hexadecimal digits.digest()
类似,不同之处在于,摘要作为长度为两倍的字符串对象返回,仅包含十六进制数字。This may be used to exchange the value safely in email or other non-binary environments.这可以用于在电子邮件或其他非二进制环境中安全地交换值。
-
hash.
copy
()¶ Return a copy (“clone”) of the hash object.返回哈希对象的副本(“克隆”)。This can be used to efficiently compute the digests of data sharing a common initial substring.这可以用来有效地计算共享公共初始子串的数据摘要。
SHAKE variable length digestsSHAKE可变长度摘要¶
The shake_128()
and shake_256()
algorithms provide variable length digests with length_in_bits//2 up to 128 or 256 bits of security. shake_128()
和shake_256()
算法提供具有length_in_bits//2的可变长度摘要,其安全性最高可达128或256位。。As such, their digest methods require a length. 因此,他们的摘要方法需要一定的长度。Maximum length is not limited by the SHAKE algorithm.最大长度不受抖动算法的限制。
-
shake.
digest
(length)¶ Return the digest of the data passed to the返回到目前为止传递给update()
method so far.update()
方法的数据摘要。This is a bytes object of size length which may contain bytes in the whole range from 0 to 255.这是一个大小为length的字节对象,它可以包含从0到255的整个范围内的字节。
-
shake.
hexdigest
(length)¶ Like与digest()
except the digest is returned as a string object of double length, containing only hexadecimal digits.digest()
类似,不同之处在于,摘要作为长度为两倍的字符串对象返回,仅包含十六进制数字。This may be used to exchange the value safely in email or other non-binary environments.这可以用于在电子邮件或其他非二进制环境中安全地交换值。
Key derivation导出密钥¶
Key derivation and key stretching algorithms are designed for secure password hashing. 密钥推导和密钥拉伸算法是为安全密码哈希而设计的。Naive algorithms such as 诸如sha1(password)
are not resistant against brute-force attacks. sha1(password)
之类的朴素算法无法抵抗暴力攻击。A good password hashing function must be tunable, slow, and include a salt.一个好的密码哈希函数必须是可调的、缓慢的,并且包含一个salt。
-
hashlib.
pbkdf2_hmac
(hash_name, password, salt, iterations, dklen=None)¶ The function provides PKCS#5 password-based key derivation function 2.该函数提供基于PKCS#5密码的密钥导出函数2。It uses HMAC as pseudorandom function.它使用HMAC作为伪随机函数。The string hash_name is the desired name of the hash digest algorithm for HMAC, e.g. ‘sha1’ or ‘sha256’.字符串hash_name是HMAC的哈希摘要算法所需的名称,例如“sha1”或“sha256”。password and salt are interpreted as buffers of bytes.password和salt被解释为字节缓冲区。Applications and libraries should limit password to a sensible length (e.g. 1024).应用程序和库应将password限制在合理的长度(例如1024)。salt should be about 16 or more bytes from a proper source, e.g.salt应该是来自适当源的16个或更多字节,例如os.urandom()
.os.urandom()
。The number of iterations should be chosen based on the hash algorithm and computing power.应根据哈希算法和计算能力选择迭代次数。As of 2022, hundreds of thousands of iterations of SHA-256 are suggested.截至2022年,建议对SHA-256进行数十万次迭代。For rationale as to why and how to choose what is best for your application, read Appendix A.2.2 of NIST-SP-800-132.有关为什么以及如何选择最适合您的应用的理由,请参阅NIST-SP-800-132的附录A.2.2。The answers on the stackexchange pbkdf2 iterations question explain in detail.stackexchange pbkdf2迭代问题的答案详细解释了这一点。dklen
is the length of the derived key.是派生密钥的长度。If dklen is如果dklen为None
then the digest size of the hash algorithm hash_name is used, e.g. 64 for SHA-512.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'New in version 3.4.版本3.4中新增。Note
A fast implementation of pbkdf2_hmac is available with OpenSSL.OpenSSL提供了pbkdf2_hmac的快速实现。The Python implementation uses an inline version ofPython实现使用hmac
.hmac
的内联版本。It is about three times slower and doesn’t release the GIL.它的速度大约慢三倍,不会释放GIL。Deprecated since version 3.10:自版本3.10以来已弃用:Slow Python implementation of pbkdf2_hmac is deprecated.不推荐使用pbkdf2_hmac的慢速Python实现。In the future the function will only be available when Python is compiled with OpenSSL.将来,该函数只有在使用OpenSSL编译Python时才可用。
-
hashlib.
scrypt
(password, *, salt, n, r, p, maxmem=0, dklen=64)¶ The function provides scrypt password-based key derivation function as defined in RFC 7914.该函数提供了RFC 7914中定义的基于scrypt密码的密钥导出函数。password and salt must be bytes-like objects. Applications and libraries should limit password to a sensible length (e.g. 1024). salt should be about 16 or more bytes from a proper source, e.g.
os.urandom()
.n is the CPU/Memory cost factor, r the block size, p parallelization factor and maxmem limits memory (OpenSSL 1.1.0 defaults to 32 MiB). dklen is the length of the derived key.
New in version 3.6.版本3.6中新增。
BLAKE2¶
BLAKE2 is a cryptographic hash function defined in RFC 7693 that comes in two flavors:
BLAKE2b
, optimized for 64-bit platforms and produces digests of any size between 1 and 64 bytes,针对64位平台进行了优化,并生成1到64字节之间的任何大小的摘要,BLAKE2s
, optimized for 8- to 32-bit platforms and produces digests of any size between 1 and 32 bytes.,针对8到32位平台进行了优化,并生成1到32字节之间的任何大小的摘要。
BLAKE2 supports keyed mode (a faster and simpler replacement for HMAC), salted hashing, personalization, and tree hashing.
Hash objects from this module follow the API of standard library’s 此模块中的哈希对象遵循标准库hashlib
objects.hashlib
对象的API。
Creating hash objects创建哈希对象¶
New hash objects are created by calling constructor functions:通过调用构造函数创建新的哈希对象:
-
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)¶
These functions return the corresponding hash objects for calculating BLAKE2b or BLAKE2s. 这些函数返回用于计算BLAKE2b或BLAKE2s的相应哈希对象。They optionally take these general parameters:它们可选地采用以下通用参数:
data
: initial chunk of data to hash, which must be bytes-like object.:要散列的初始数据块,必须是类似字节的对象。It can be passed only as positional argument.digest_size
: size of output digest in bytes.:输出摘要的大小(字节)。key
: key for keyed hashing (up to 64 bytes for BLAKE2b, up to 32 bytes for BLAKE2s).:键控哈希的键(BLAKE2b最多64字节,BLAKE2s最多32字节)。salt
: salt for randomized hashing (up to 16 bytes for BLAKE2b, up to 8 bytes for BLAKE2s).:用于随机哈希的salt(BLAKE2b最多16个字节,BLAKE2s最多8个字节)。person
: personalization string (up to 16 bytes for BLAKE2b, up to 8 bytes for BLAKE2s).:个性化设置字符串(BLAKE2b最多16个字节,BLAKE2s最多8个字节)。
The following table shows limits for general parameters (in bytes):下表显示了常规参数的限制(字节):
Hash |
digest_size |
len(key) |
len(salt) |
len(person) |
---|---|---|---|---|
BLAKE2b |
64 |
64 |
16 |
16 |
BLAKE2s |
32 |
32 |
8 |
8 |
Note
BLAKE2 specification defines constant lengths for salt and personalization parameters, however, for convenience, this implementation accepts byte strings of any size up to the specified length. BLAKE2规范为salt和个性化参数定义了恒定长度,然而,为了方便起见,该实现接受任何大小的字节字符串,直到指定的长度。If the length of the parameter is less than specified, it is padded with zeros, thus, for example, 如果参数的长度小于指定的长度,则用零填充,因此,例如,b'salt'
and b'salt\x00'
is the same value. b'salt'
和b'salt\x00'
是相同的值。(This is not the case for key.)(对于key,情况并非如此。)
These sizes are available as module constants described below.这些尺寸可作为下文所述的模块常数提供。
Constructor functions also accept the following tree hashing parameters:构造函数还接受以下树哈希参数:
fanout
: fanout (0 to 255, 0 if unlimited, 1 in sequential mode).:扇出(0到255,如果不受限制,则为0,顺序模式下为1)。depth
: maximal depth of tree (1 to 255, 255 if unlimited, 1 in sequential mode).:树的最大深度(1到255,如果不受限制,则为255,顺序模式下为1)。leaf_size
: maximal byte length of leaf (0 to:叶的最大字节长度(2**32-1
, 0 if unlimited or in sequential mode).0到2**32-1
,如果不受限制或处于顺序模式,则为0)。node_offset
: node offset (0 to:节点偏移量(BLAKE2b为0到2**64-1
for BLAKE2b, 0 to2**48-1
for BLAKE2s, 0 for the first, leftmost, leaf, or in sequential mode).2**64-1
,BLAKE2s为0到2**48-1
,第一个、最左侧、叶或顺序模式为0)。node_depth
: node depth (0 to 255, 0 for leaves, or in sequential mode).:节点深度(0到255,叶为0,或在顺序模式下)。inner_size
: inner digest size (0 to 64 for BLAKE2b, 0 to 32 for BLAKE2s, 0 in sequential mode).:内部摘要大小(BLAKE2b为0到64,BLAKE2s为0到32,顺序模式为0)。last_node
: boolean indicating whether the processed node is the last one (False for sequential mode).:布尔值,指示处理的节点是否是最后一个节点(顺序模式为False
)。

See section 2.10 in BLAKE2 specification for comprehensive review of tree hashing.有关树哈希的全面审查,请参阅BLAKE2规范中的第2.10节。
Constants常数¶
-
blake2b.
SALT_SIZE
¶
-
blake2s.
SALT_SIZE
¶
Salt length (maximum length accepted by constructors).Salt长度(构造函数接受的最大长度)。
-
blake2b.
PERSON_SIZE
¶
-
blake2s.
PERSON_SIZE
¶
Personalization string length (maximum length accepted by constructors).个性化字符串长度(构造函数接受的最大长度)。
-
blake2b.
MAX_KEY_SIZE
¶
-
blake2s.
MAX_KEY_SIZE
¶
Maximum key size.最大密钥大小。
-
blake2b.
MAX_DIGEST_SIZE
¶
-
blake2s.
MAX_DIGEST_SIZE
¶
Maximum digest size that the hash function can output.哈希函数可以输出的最大摘要大小。
Examples示例¶
Simple hashing简单散列¶
To calculate hash of some data, you should first construct a hash object by calling the appropriate constructor function (要计算某些数据的哈希,您应该首先通过调用适当的构造函数(blake2b()
or blake2s()
), then update it with the data by calling update()
on the object, and, finally, get the digest out of the object by calling digest()
(or hexdigest()
for hex-encoded string).blake2b()
或blake2s()
)构造一个哈希对象,然后通过调用对象上的update()
用数据更新它,最后,通过调用digest()
从对象中获取摘要(或十六进制编码字符串的hexdigest()
)。
>>> from hashlib import blake2b
>>> h = blake2b()
>>> h.update(b'Hello world')
>>> h.hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'
As a shortcut, you can pass the first chunk of data to update directly to the constructor as the positional argument:作为一种快捷方式,您可以将要更新的第一块数据作为位置参数直接传递给构造函数:
>>> from hashlib import blake2b
>>> blake2b(b'Hello world').hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'
You can call 您可以根据需要多次调用hash.update()
as many times as you need to iteratively update the hash:hash.update()
,以迭代更新哈希:
>>> from hashlib import blake2b
>>> items = [b'Hello', b' ', b'world']
>>> h = blake2b()
>>> for item in items:
... h.update(item)
>>> h.hexdigest()
'6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183'
Using different digest sizes使用不同的摘要大小¶
BLAKE2 has configurable size of digests up to 64 bytes for BLAKE2b and up to 32 bytes for BLAKE2s. BLAKE2具有可配置的摘要大小,BLAKE2b最多64字节,BLAKE2最多32字节。For example, to replace SHA-1 with BLAKE2b without changing the size of output, we can tell BLAKE2b to produce 20-byte digests:例如,为了在不改变输出大小的情况下用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
Hash objects with different digest sizes have completely different outputs (shorter hashes are not prefixes of longer hashes); BLAKE2b and BLAKE2s produce different outputs even if the output length is the same:具有不同摘要大小的散列对象具有完全不同的输出(较短的散列不是较长散列的前缀);即使输出长度相同,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'
Keyed hashing键控哈希¶
Keyed hashing can be used for authentication as a faster and simpler replacement for Hash-based message authentication code (HMAC). 密钥散列可以用于身份验证,作为基于散列的消息身份验证码(HMAC)的更快、更简单的替代。BLAKE2 can be securely used in prefix-MAC mode thanks to the indifferentiability property inherited from BLAKE.由于继承自BLAKE的无差别特性,BLAKE2可以在前缀MAC模式下安全使用。
This example shows how to get a (hex-encoded) 128-bit authentication code for message 此示例显示了如何使用密钥b'message data'
with key b'pseudorandom key'
: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'
As a practical example, a web application can symmetrically sign cookies sent to users and later verify them to make sure they weren’t tampered with:作为一个实际示例,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
Even though there’s a native keyed hashing mode, BLAKE2 can, of course, be used in HMAC construction with 尽管存在本机密钥散列模式,BLAKE2当然可以用于hmac
module:hmac
模块的HMAC构造:
>>> import hmac, hashlib
>>> m = hmac.new(b'secret key', digestmod=hashlib.blake2s)
>>> m.update(b'message')
>>> m.hexdigest()
'e3c8102868d28b5ff85fc35dda07329970d1a01e273c37481326fe0c861c8142'
Randomized hashing随机散列¶
By setting salt parameter users can introduce randomization to the hash function. 通过设置salt参数,用户可以将随机化引入哈希函数。Randomized hashing is useful for protecting against collision attacks on the hash function used in digital signatures.随机哈希有助于防止对数字签名中使用的哈希函数的冲突攻击。
Randomized hashing is designed for situations where one party, the message preparer, generates all or part of a message to be signed by a second party, the message signer.随机哈希是为一方(消息编制者)生成要由第二方(消息签名者)签名的全部或部分消息的情况而设计的。If the message preparer is able to find cryptographic hash function collisions (i.e., two messages producing the same hash value), then they might prepare meaningful versions of the message that would produce the same hash value and digital signature, but with different results (e.g., transferring $1,000,000 to an account, rather than $10).如果消息编制者能够找到加密哈希函数冲突(即,两条消息产生相同的哈希值),则他们可能会编制有意义的消息版本,该消息将产生相同的散列值和数字签名,但结果不同(例如,将1000000美元转移到一个帐户,而不是10美元)。Cryptographic hash functions have been designed with collision resistance as a major goal, but the current concentration on attacking cryptographic hash functions may result in a given cryptographic hash function providing less collision resistance than expected.密码散列函数的设计以抗冲突为主要目标,但当前集中攻击密码散列功能可能导致给定密码散列函提供的抗冲突能力低于预期。Randomized hashing offers the signer additional protection by reducing the likelihood that a preparer can generate two or more messages that ultimately yield the same hash value during the digital signature generation process — even if it is practical to find collisions for the hash function.随机哈希通过降低制备者在数字签名生成过程中生成两个或多个最终生成相同哈希值的消息的可能性,为签名者提供了额外的保护-即使发现哈希函数的冲突是可行的。However, the use of randomized hashing may reduce the amount of security provided by a digital signature when all portions of the message are prepared by the signer.然而,当签名者准备好消息的所有部分时,使用随机哈希可能会减少数字签名提供的安全性。(NIST SP-800-106 “Randomized Hashing for Digital Signatures”)
In BLAKE2 the salt is processed as a one-time input to the hash function during initialization, rather than as an input to each compression function.在BLAKE2中,salt在初始化期间作为哈希函数的一次性输入进行处理,而不是作为每个压缩函数的输入。
Warning
Salted hashing (or just hashing) with BLAKE2 or any other general-purpose cryptographic hash function, such as SHA-256, is not suitable for hashing passwords. 使用BLAKE2或任何其他通用加密哈希函数(如SHA-256)进行盐渍哈希(或仅仅是哈希)不适合对密码进行哈希。See BLAKE2 FAQ for more information.有关更多信息,请参阅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
Personalization个性化¶
Sometimes it is useful to force hash function to produce different digests for the same input for different purposes. 有时,强制哈希函数为不同目的的相同输入生成不同摘要是有用的。Quoting the authors of the Skein hash function:引用Skein哈希函数的作者:
We recommend that all application designers seriously consider doing this; we have seen many protocols where a hash that is computed in one part of the protocol can be used in an entirely different part because two hash computations were done on similar or related data, and the attacker can force the application to make the hash inputs the same.我们建议所有应用程序设计者认真考虑这样做;我们已经看到许多协议,其中在协议的一部分中计算的哈希可以在完全不同的部分中使用,因为两个哈希计算是在相似或相关的数据上进行的,攻击者可以强制应用程序使哈希输入相同。Personalizing each hash function used in the protocol summarily stops this type of attack.对协议中使用的每个哈希函数进行个性化处理可立即停止此类攻击。(The Skein Hash Function Family, p. 21)
BLAKE2 can be personalized by passing bytes to the person argument: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'
Personalization together with the keyed mode can also be used to derive different keys from a single one.个性化和键控模式也可用于从单个键导出不同的键。
>>> 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=
Tree mode树模式¶
Here’s an example of hashing a minimal tree with two leaf nodes:下面是对具有两个叶节点的最小树进行哈希的示例:
10
/ \
00 01
This example uses 64-byte internal digests, and returns the 32-byte final digest:本例使用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'
Credits信用¶
BLAKE2 was designed by Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O’Hearn, and Christian Winnerlein based on SHA-3 finalist BLAKE created by Jean-Philippe Aumasson, Luca Henzen, Willi Meier, and Raphael C.-W. Phan.BLAKE2由Jean-Philippe Aumasson、Samuel Neves、Zooko Wilcox-O'Hearn和Christian Winnerlein根据Jean-Philippe Aumasson、Luca Henzen、Willi Meier和Raphael C.-W.创造的SHA-3决赛选手BLAKE设计。潘。
It uses core algorithm from ChaCha cipher designed by Daniel J. Bernstein.它使用Daniel J.Bernstein设计的ChaCha密码的核心算法
The stdlib implementation is based on pyblake2 module. stdlib实现基于pyblake2模块。It was written by Dmitry Chestnykh based on C implementation written by Samuel Neves. 它是由Dmitry Chestnykh基于Samuel Neves编写的C实现编写的。The documentation was copied from pyblake2 and written by Dmitry Chestnykh.该文档是从pyblake2复制的,由Dmitry Chestnykh编写。
The C code was partly rewritten for Python by Christian Heimes.C代码部分由Christian Heimes为Python重写。
The following public domain dedication applies for both C hash function implementation, extension code, and this documentation:以下公共域奉献适用于C哈希函数实现、扩展代码和本文档:
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.在法律允许的范围内,作者已将本软件的所有版权、相关权利和相邻权利专用于全球公共领域。This software is distributed without any warranty.本软件无任何保修。
You should have received a copy of the CC0 Public Domain Dedication along with this software.您应该已经收到了一份CC0公共域奉献的副本以及此软件。If not, see https://creativecommons.org/publicdomain/zero/1.0/.如果没有,请参阅https://creativecommons.org/publicdomain/zero/1.0/。
The following people have helped with development or contributed their changes to the project and the public domain according to the Creative Commons Public Domain Dedication 1.0 Universal:根据知识共享公共领域奉献1.0 Universal,以下人员帮助开发项目或为项目和公共领域做出了贡献:
Alexandr Sokolovskiy
See also参阅
- Module
hmac
A module to generate message authentication codes using hashes.使用哈希生成消息验证码的模块。- Module
base64
Another way to encode binary hashes for non-binary environments.为非二进制环境编码二进制哈希的另一种方法。- https://blake2.net
Official BLAKE2 website.BLAKE2官方网站。- https://csrc.nist.gov/csrc/media/publications/fips/180/2/archive/2002-08-01/documents/fips180-2.pdf
The FIPS 180-2 publication on Secure Hash Algorithms.FIPS 180-2关于安全哈希算法的出版物。- https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms
Wikipedia article with information on which algorithms have known issues and what that means regarding their use.Wikipedia文章提供了关于哪些算法存在已知问题的信息,以及它们的使用意味着什么。- https://www.ietf.org/rfc/rfc8018.txt
PKCS #5: Password-Based Cryptography Specification Version 2.1PKCS#5:基于密码的加密规范版本2.1- https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf
NIST Recommendation for Password-Based Key Derivation.NIST关于基于密码的密钥推导的建议。