HMAC、PBKDF2 與 HKDF 計算器

用 HMAC-MD5、HMAC-SHA-1、HMAC-SHA-256、HMAC-SHA-384 或 HMAC-SHA-512(RFC 2104)對文本、hex 位元組或整個檔案計算帶金鑰的訊息認證碼 —— 金鑰支援文本、hex 或 Base64。也可以用 PBKDF2(RFC 8018)和 HKDF(RFC 5869)派生金鑰。每個結果都可以渲染為 hex、大寫 hex、Base64 或 Base64url。純摘要請看雜湊生成器;校驗和請看CRC 計算器;JWT 裡的 HMAC 請看JWT 解碼器。
完全本地執行 —— 金鑰和訊息永遠不會離開你的標籤頁。檔案最大 200 MB。
構造: 輸出:
HMAC 演算法: RFC 2104 — MD5 變體需要 md5.js(本頁已載入)。
Hex 讀取方式容忍空格、冒號和 0x 字首;Base64 須為標準格式(帶或不帶填充)。
空金鑰在 RFC 2104 下合法但幾乎總是錯誤 —— 沒有金鑰的 HMAC 只是一個慢雜湊。
第一行記錄所用的確切引數(演算法、讀取方式、輸入大小),因此複製粘貼出的結果總是可復現的。
你需要哪種構造?
HMAC 把共享秘密加上訊息變成一個認證器:持有金鑰的接收方可以重算它並檢測篡改。它就是每份簽名 JWT 裡的“HS256”(見JWT 解碼器),也是世界上大半 API 請求籤名方案的一半。PBKDF2 用於把人類口令拉伸成金鑰:它把 HMAC 重複數千次,使攻擊者猜測每個口令都要付出同樣的延遲。HKDF 面向協議金鑰:它接收已經隨機的保密位元組(如 DH 共享秘密),安全地擴充套件成多個繫結用途的金鑰 —— TLS 1.3 的全部流量金鑰就是這樣派生的。經驗法則:認證 → HMAC;口令 → PBKDF2(或 scrypt/Argon2,釋出後見密碼雜湊生成器);均勻秘密 → HKDF。
自測
用已發表的向量測試本頁引擎:10 個 HMAC 錨點(RFC 2202/4231 風格,五種演算法 × 兩種輸入)、6 個 PBKDF2 錨點(SHA-1 和 SHA-256 各三個迭代次數)以及 RFC 5869 HKDF 的四個測試用例 A.1–A.4。任何資料都不會被髮送。
HMAC、PBKDF2 與 HKDF —— 從零講清帶金鑰雜湊
一句話:像 SHA-256 這樣的裸雜湊誰都能算,所以它證明不了訊息是誰發的 —— HMAC 混入一個秘密金鑰,使只有持有金鑰的人才能產生(或驗證)摘要;PBKDF2 和 HKDF 則複用同一套 HMAC 機器,把秘密變成金鑰:對口令要慢,對已隨機的材料要快。
HMAC 是什麼(RFC 2104)

構造。HMAC 是兩次雜湊,不是一次。金鑰被填充到雜湊的塊大小(MD5/SHA-1/SHA-256 為 64 位元組,SHA-384/512 為 128 位元組);訊息先與“金鑰 XOR 固定內層填充”一起雜湊一次,得到的摘要再與“金鑰 XOR 固定外層填充”雜湊一次。只要底層雜湊是像樣的偽隨機函式,這個雙夾層就被證明是安全的 —— 這也是 HMAC-MD5 至今仍能抵禦攻破裸 MD5 的實用碰撞攻擊的原因(儘管它反正已經退役,見下文)。

金鑰。任意長度都可以:短於塊大小的直接使用(但不足 32 位元組會被人皺眉),更長的會先被雜湊。本頁允許把金鑰按文本、hex 或 Base64 輸入,這樣 64 個 hex 字元的生產金鑰不會被誤當 64 字元的文本口令貼上 —— 輸出行裡記錄讀取方式正是為了這個。

在哪裡會遇到它。JWT 頭部的 HS256 欄位就是對 base64url 編碼的令牌部分做 HMAC-SHA-256(貼上 HS256 金鑰時,本站的JWT 解碼器算的正是它)。Webhook 簽名(Stripe、GitHub)、AWS SigV4、TLS 記錄保護(舊版本)以及 OpenSSH 的近親 umac-64@openssh.com 都屬於同一家族。

為什麼不直接 hash(message || key)?長度擴充套件攻擊:MD5/SHA-1/SHA-2 家族的每種雜湊都允許知道 H(secret || msg) 的攻擊者在沒有秘密的情況下算出 H(secret || msg || padding || anything)。HMAC 的內外分層消滅了這一類攻擊。這是 API 簽名程式碼裡最常見的 DIY 錯誤 —— 也是 HMAC 存在的理由。

PBKDF2 是什麼(RFC 8018)

慢是設計出來的。一個口令可能只有 40 位元的真實熵;攻擊者的 GPU 每秒能試數十億次裸 SHA-256。PBKDF2 把 HMAC(password, salt) 反覆執行 —— iter 次 —— 讓你和攻擊者每次猜測付出同樣的 iter 次 HMAC。這裡的預設值是 HMAC-SHA-256 的 600,000 次迭代,即 OWASP 口令儲存速查表的基線;滑塊上限一千萬,因為隨著硬體提速,安全建議也會不斷上調。

鹽。每口令的隨機鹽讓相同口令的使用者不再雜湊出相同結果,預計算表(彩虹表)也就失效了。鹽不是秘密 —— 它就存在雜湊旁邊 —— 它只需要唯一。16 個隨機位元組是慣例。

已知弱點。PBKDF2 抗 CPU 但不抗記憶體:GPU 和 ASIC 並行化它毫不費力。所以在設計口令雜湊儲存時,現代建議是 scrypt 或 Argon2id(本家族的密碼雜湊生成器頁面覆蓋了它們),而 PBKDF2 仍是相容性與 FIPS-140 場景的正確答案。

HKDF 是什麼(RFC 5869)

先提取,再擴充套件。HKDF 做兩件事。Extract:把可能不均勻的輸入金鑰材料(例如 Diffie–Hellman 共享秘密)與鹽一起壓成一個短的偽隨機金鑰 PRK = HMAC(salt, IKM)。Expand:把 PRK 拉伸到最多 255 個雜湊塊的任意長度,每個輸出塊與前一塊鏈式相連並由 info 欄位標記用途。結果是一個秘密可以安全地派生出加密金鑰、MAC 金鑰和 IV,彼此分離。

不適用於口令。HKDF 假定輸入已有充分熵 —— 它每 32 個輸出位元組只做一次 HMAC,人類口令幾乎瞬間穿過它,這正是攻擊者想要的。用 HKDF 而不是 PBKDF2 處理口令是經典設計錯誤;info 欄位是用途標籤("client traffic key"、"server iv"),不是額外熵。

在哪裡會遇到它。TLS 1.3 從握手秘密經 HKDF 派生它使用的每一個金鑰;WireGuard、Signal、EAP-TLS 1.3 和 JSON Web Encryption(作為直接金鑰協商 KDF)都在同一棵家族樹上。

錨點值 —— 在本頁復現它們

前兩張表是本頁樣例按鈕和自測所用的測試向量(金鑰 "key"、訊息“The quick brown fox jumps over the lazy dog”;然後是 RFC 風格的 16 位元組 0x0b 金鑰與訊息“Hi There”)。全部由獨立原生實現生成,並在本頁複核。

“fox” 的 HMAC,金鑰 = key摘要(hex)
HMAC-MD580070713463e7749b90c2dc24911e275
HMAC-SHA-1de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
HMAC-SHA-256f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
HMAC-SHA-384d7f4727e2c0b39ae0f1e40cc96f60242d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237
HMAC-SHA-512b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a
KDF 錨點引數輸出(hex,首位元組)
PBKDF2-HMAC-SHA-1password / salt,c=4096,32 位元組4b007901b765489abead49d926f721d065a429c12e463f6c4cd79401085b03db
PBKDF2-HMAC-SHA-256password / salt,c=4096,32 位元組c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a
HKDF-SHA-256 (RFC 5869 A.1)IKM=0x0b×22,鹽=00..0c,info=f0..f9,L=423cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865
HKDF-SHA-256 (RFC 5869 A.2)IKM=00..4f,鹽=60..af,info=b0..ff,L=82b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c…
HKDF-SHA-256 (RFC 5869 A.3)IKM=0x0b×22,空鹽與空 info,L=428da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
常見誤區
  • 把 HMAC 當加密。HMAC 證明完整性與來源(給定共享秘密);它不隱藏任何東西。沒有金鑰的人仍然能看到完整訊息。
  • 把 HMAC 當簽名。數字簽名是公鑰的:一人簽名,任何人可驗證。HMAC 是對稱的:每個驗證者同樣能偽造。不可抵賴需要 RSA/ECDSA(本家族的 RSA 工具釋出後可用),不是 HMAC。
  • 金鑰讀取方式不匹配。把 64 字元的 hex 串按文本貼上進金鑰框會變成 64 位元組而不是 32 —— HMAC 完全不同。本頁在輸出行列印讀取方式;兩個工具結果不一致時,先比這一項。
  • PBKDF2 迭代次數太低。2000 年時 1,000 次還算合理;今天的 GPU 叢集秒殺它。如果你的系統還在存 1,000 次迭代的雜湊,規劃一次“登入時重雜湊”的遷移吧。
  • 對口令用 HKDF。每個輸出塊一次 HMAC 意味著口令瞬間通過 —— 口令用 PBKDF2(或 Argon2id),高熵秘密才用 HKDF。
  • 一個派生金鑰處處用。修復是免費的:用不同的 info 標籤派生獨立的金鑰。同一 IKM 不同標籤派生的兩個金鑰在設計上就是獨立的。
常見問題

HMAC-MD5 被破了嗎?作為抗碰撞雜湊,MD5 已經死了,但 HMAC-MD5 的安全性取決於 MD5 作為偽隨機函式的表現,尚無已知實用破解。反正也退役了 —— 除非為了相容舊協議,沒有理由在 HMAC-SHA-256 可用時選它。

HMAC 金鑰該多長?至少等於雜湊輸出長度(SHA-256 為 32 位元組),並由 CSPRNG 生成。短於摘要長度的金鑰允許使用,但每一位不足都直接降低安全性。

PBKDF2 迭代越多就越“安全”嗎,可以無限加?它線性提高攻擊者的成本,但也線性提高你的登入成本。博弈在於選擇使用者能容忍的最大次數 —— OWASP 的數字就是按這個校準的。

為什麼 HKDF 上限是 255 × 雜湊長度?擴充套件迴圈是 T(i) = HMAC(PRK, T(i-1) || info || i),計數器 i 只有一個位元組 —— 255 是最大計數值,這是 RFC 5869 的硬性結構限制,不是策略選擇。

本頁的 PBKDF2 和密碼雜湊生成器有什麼區別?同一演算法,不同工作。本頁派生原始金鑰位元組供你在別處使用;密碼雜湊頁生成的是儲存憑據字串(內嵌鹽與引數),並對照它們驗證貼上的候選口令。