關(guān)于HMAC原理和JS加密合作分工的秘密

前言

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

WX20231204-144436@2x.png

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 簽名的邏輯流程可以分為三步:

  1. 請求:客戶端將數(shù)據(jù)和簽名一起發(fā)送給服務(wù)端。

  2. 生成簽名:服務(wù)端使用相同的密鑰和接收到的數(shù)據(jù)重新計(jì)算簽名。

  3. 對比簽名:將重新計(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)頁接口。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容