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 關於基於密碼的金鑰派生的建議。