hashlib — 安全雜湊與訊息摘要

原始碼: Lib/hashlib.py


此模組為多種不同的雜湊演算法實現了一個通用的介面。其中包括 FIPS 安全雜湊演算法 SHA224、SHA256、SHA384、SHA512(定義於 FIPS 180-4 標準)、SHA-3 系列(定義於 FIPS 202 標準),以及舊有演算法 SHA1(曾是 FIPS 的一部分)和 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-另請參閱部分。

在 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 版更改: 如果 OpenSSL 提供了 SHA3 和 SHAKE,hashlib 現在會使用 OpenSSL 的實現。

在 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 物件等類似物件。fileobj 必須以阻塞模式開啟,否則可能會引發 BlockingIOError

該函式可能會繞過 Python 的 I/O,直接使用來自 fileno() 的檔案描述符。在此函式返回或引發異常後,應假定 fileobj 處於未知狀態。關閉 fileobj 是呼叫者的責任。

digest 必須是雜湊演算法名稱的 *str*、雜湊建構函式,或返回雜湊物件的可呼叫物件。

示例

>>> import io, hashlib, hmac
>>> with open("library/hashlib.rst", "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 版本中新增。

在 3.14 版更改: 現在如果檔案以非阻塞模式開啟,會引發 BlockingIOError。以前,摘要中會新增虛假的空位元組。

金鑰派生

金鑰派生和金鑰拉伸演算法專為安全密碼雜湊而設計。像 sha1(password) 這樣的樸素演算法無法抵抗暴力破解攻擊。一個好的密碼雜湊函式必須是可調的、緩慢的,並且包含一個鹽(salt)

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)

該函式提供了 RFC 7914 中定義的 scrypt 基於密碼的金鑰派生函式。

passwordsalt 必須是 類位元組物件。應用程式和庫應將 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 位元組。例如,要用 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) 的更快、更簡單的替代方案。由於繼承自 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 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 雜湊函式家族,第 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 Aumasson*、*Samuel Neves*、*Zooko Wilcox-O'Hearn* 和 *Christian Winnerlein* 設計,基於由 *Jean-Philippe Aumasson*、*Luca Henzen*、*Willi 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 公共領域貢獻宣告的副本。如果沒有,請參閱 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 對基於密碼的金鑰派生的建議。