前言
文章有任何問題請咨詢官方客服

1?? HMAC 是什么?
HMAC 就像是一把“鎖 + 哈?!钡慕M合。想象一下,你有一份重要的數(shù)據(jù),就像一封重要的信件,你想確保這封信在傳遞過程中不被篡改,還能證明這封信確實(shí)是你發(fā)出的。這時(shí)候,HMAC 加密就派上用場了。它會(huì)用一個(gè)密鑰(就像一把特殊的鎖)和你的數(shù)據(jù)一起進(jìn)行哈希運(yùn)算(可以理解為把信件和鎖一起放進(jìn)一個(gè)魔法盒子,經(jīng)過一番變化,出來一個(gè)獨(dú)特的簽名),然后生成一個(gè)簽名。這個(gè)簽名就像是信件上的一個(gè)特殊標(biāo)記,只有用同樣的密鑰和數(shù)據(jù)才能生成相同的標(biāo)記。
下面這張圖展示了數(shù)據(jù) + 密鑰 → 哈希 → 簽名的流程: [圖片上傳失敗...(image-a69efb-1758436324760)]
2?? HMAC 有啥用?
HMAC 在很多場景中都非常有用,比如:
API 接口簽名驗(yàn)證:當(dāng)客戶端向服務(wù)端發(fā)送請求時(shí),為了確保請求是合法的,沒有被中間人篡改,會(huì)使用 HMAC 對請求數(shù)據(jù)進(jìn)行簽名。服務(wù)端接收到請求后,會(huì)重新計(jì)算簽名并進(jìn)行驗(yàn)證。就像你去銀行取錢,銀行會(huì)通過一些特殊的驗(yàn)證方式來確認(rèn)是你本人在操作。
防止數(shù)據(jù)篡改:在數(shù)據(jù)傳輸過程中,使用 HMAC 可以檢測數(shù)據(jù)是否被修改。如果數(shù)據(jù)被篡改,重新計(jì)算的簽名會(huì)與原來的簽名不同。就像你給朋友寄了一個(gè)密封的包裹,朋友收到后發(fā)現(xiàn)封條被破壞了,就知道包裹可能被打開過。
登錄驗(yàn)證:在用戶登錄時(shí),可以使用 HMAC 對用戶的密碼進(jìn)行加密驗(yàn)證。這樣可以增加密碼的安全性,防止密碼在傳輸過程中被竊取。
下面是客戶端和服務(wù)端之間的交互流程圖: [圖片上傳失敗...(image-68bfc4-1758436324760)]
3?? HMAC 工作原理圖解
HMAC 的底層計(jì)算流程有點(diǎn)像一個(gè)“洋蔥模型”或“內(nèi)外殼層疊結(jié)構(gòu)”。簡單來說,它會(huì)先將密鑰和一些特定的值進(jìn)行處理,形成內(nèi)外兩層,然后分別與數(shù)據(jù)進(jìn)行哈希運(yùn)算,最后再進(jìn)行一次哈希運(yùn)算得到最終的簽名。
下面這張圖展示了 HMAC 的底層計(jì)算流程: [圖片上傳失敗...(image-1f8bdc-1758436324760)]
4?? 簡單代碼演示(Python + JS)
Python 示例代碼
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" cid="n105" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(0, 122, 255); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">import hmac
import hashlib
要加密的數(shù)據(jù)
data = b"Hello, HMAC!"
密鑰
key = b"mysecretkey"
創(chuàng)建 HMAC 對象,使用 SHA256 算法
h = hmac.new(key, data, hashlib.sha256)
獲取簽名
signature = h.hexdigest()
print("Python 計(jì)算的簽名:", signature)</pre>
JavaScript 示例代碼
<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="javascript" cid="n107" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; caret-color: rgb(0, 122, 255); color: rgb(51, 51, 51); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-indent: 0px; text-transform: none; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">const crypto = require('crypto');
// 要加密的數(shù)據(jù)
const data = 'Hello, HMAC!';
// 密鑰
const key = 'mysecretkey';
// 創(chuàng)建 HMAC 對象,使用 SHA256 算法
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
// 獲取簽名
const signature = hmac.digest('hex');
console.log('JavaScript 計(jì)算的簽名:', signature);</pre>
這里可以想象代碼運(yùn)行后輸出結(jié)果的截圖風(fēng)格配圖,由于無法實(shí)際提供截圖,你可以自行運(yùn)行代碼查看結(jié)果。
5?? 服務(wù)端如何驗(yàn)證簽名
服務(wù)端校驗(yàn) HMAC 簽名的邏輯流程可以分為三步:
請求:客戶端將數(shù)據(jù)和簽名一起發(fā)送給服務(wù)端。
生成簽名:服務(wù)端使用相同的密鑰和接收到的數(shù)據(jù)重新計(jì)算簽名。
對比簽名:將重新計(jì)算的簽名與客戶端發(fā)送的簽名進(jìn)行比較,如果相同,則說明數(shù)據(jù)沒有被篡改,請求是合法的。
下面這張圖展示了服務(wù)端校驗(yàn) HMAC 簽名的邏輯流程: [圖片上傳失敗...(image-273fd6-1758436324760)]
6?? HMAC 和普通 Hash 的區(qū)別
HMAC 和普通哈希的主要區(qū)別在于是否使用了密鑰。普通哈希是對數(shù)據(jù)進(jìn)行單向轉(zhuǎn)換,生成一個(gè)固定長度的哈希值,但無法保證數(shù)據(jù)的完整性和真實(shí)性。而 HMAC 使用了一個(gè)密鑰,使得生成的簽名更加安全,只有擁有相同密鑰的人才能生成相同的簽名。
下面是一個(gè)表格對比 HMAC 和普通哈希的區(qū)別:
| 比較項(xiàng) | HMAC | 普通 Hash |
|---|---|---|
| 是否使用密鑰 | 是 | 否 |
| 安全性 | 高,可驗(yàn)證數(shù)據(jù)完整性和真實(shí)性 | 低,僅能保證數(shù)據(jù)單向轉(zhuǎn)換 |
| 應(yīng)用場景 | API 簽名、數(shù)據(jù)驗(yàn)證等 | 數(shù)據(jù)存儲(chǔ)、文件校驗(yàn)等 |
下面這張圖用鎖 vs 鏈條的意象表達(dá)了“帶密鑰的更安全”: [圖片上傳失敗...(image-73d13f-1758436324760)]
7?? 常見問題答疑(FAQ)
可以用在前端嗎?
可以,但需要注意密鑰的安全性。在前端使用 HMAC 時(shí),密鑰不能暴露在客戶端代碼中,否則會(huì)存在安全風(fēng)險(xiǎn)。一般來說,前端可以使用公鑰或臨時(shí)密鑰進(jìn)行簽名,然后在服務(wù)端進(jìn)行驗(yàn)證。
支持哪些哈希算法?
HMAC 可以使用多種哈希算法,如 SHA-1、SHA-256、MD5 等。不同的應(yīng)用場景可以選擇不同的哈希算法,一般建議使用安全性較高的算法,如 SHA-256。
是否會(huì)被截獲?
雖然 HMAC 可以保證數(shù)據(jù)的完整性和真實(shí)性,但如果密鑰被泄露,簽名就可能被偽造。因此,保護(hù)密鑰的安全非常重要。此外,在數(shù)據(jù)傳輸過程中,還可以結(jié)合其他安全措施,如 HTTPS 協(xié)議,來防止數(shù)據(jù)被截獲。
8?? 總結(jié) + 使用建議
總結(jié)
HMAC 是一種基于哈希算法的消息認(rèn)證碼,它通過使用密鑰和數(shù)據(jù)進(jìn)行哈希運(yùn)算,生成一個(gè)簽名,用于驗(yàn)證數(shù)據(jù)的完整性和真實(shí)性。HMAC 在很多場景中都有廣泛的應(yīng)用,如 API 接口簽名驗(yàn)證、防止數(shù)據(jù)篡改、登錄驗(yàn)證等。
使用建議
選擇合適的哈希算法:根據(jù)應(yīng)用場景的安全需求,選擇安全性較高的哈希算法,如 SHA-256。
保護(hù)密鑰安全:密鑰是 HMAC 安全的關(guān)鍵,要確保密鑰不被泄露??梢允褂冒踩姆绞酱鎯?chǔ)和傳輸密鑰,如使用密鑰管理系統(tǒng)。
結(jié)合其他安全措施:在實(shí)際應(yīng)用中,HMAC 可以結(jié)合其他安全措施,如 HTTPS 協(xié)議、訪問控制等,來提高系統(tǒng)的安全性。
結(jié)語
很多加密方案,結(jié)合jsjiami的加密,可以有效的保護(hù)網(wǎng)頁接口。