前言
文章有任何问题请咨询官方客服
1️⃣ HMAC 是什么?
HMAC 就像是一把“锁 + 哈希”的组合。想象一下,你有一份重要的数据,就像一封重要的信件,你想确保这封信在传递过程中不被篡改,还能证明这封信确实是你发出的。这时候,HMAC 加密就派上用场了。它会用一个密钥(就像一把特殊的锁)和你的数据一起进行哈希运算(可以理解为把信件和锁一起放进一个魔法盒子,经过一番变化,出来一个独特的签名),然后生成一个签名。这个签名就像是信件上的一个特殊标记,只有用同样的密钥和数据才能生成相同的标记。
下面这张图展示了数据 + 密钥 → 哈希 → 签名的流程: [图片上传失败...(image-a69efb-1758436324760)]
2️⃣ HMAC 有啥用?
HMAC 在很多场景中都非常有用,比如:
API 接口签名验证:当客户端向服务端发送请求时,为了确保请求是合法的,没有被中间人篡改,会使用 HMAC 对请求数据进行签名。服务端接收到请求后,会重新计算签名并进行验证。就像你去银行取钱,银行会通过一些特殊的验证方式来确认是你本人在操作。
防止数据篡改:在数据传输过程中,使用 HMAC 可以检测数据是否被修改。如果数据被篡改,重新计算的签名会与原来的签名不同。就像你给朋友寄了一个密封的包裹,朋友收到后发现封条被破坏了,就知道包裹可能被打开过。
登录验证:在用户登录时,可以使用 HMAC 对用户的密码进行加密验证。这样可以增加密码的安全性,防止密码在传输过程中被窃取。
下面是客户端和服务端之间的交互流程图: [图片上传失败...(image-68bfc4-1758436324760)]
3️⃣ HMAC 工作原理图解
HMAC 的底层计算流程有点像一个“洋葱模型”或“内外壳层叠结构”。简单来说,它会先将密钥和一些特定的值进行处理,形成内外两层,然后分别与数据进行哈希运算,最后再进行一次哈希运算得到最终的签名。
下面这张图展示了 HMAC 的底层计算流程: [图片上传失败...(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
要加密的数据
data = b"Hello, HMAC!"
密钥
key = b"mysecretkey"
创建 HMAC 对象,使用 SHA256 算法
h = hmac.new(key, data, hashlib.sha256)
获取签名
signature = h.hexdigest()
print("Python 计算的签名:", 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');
// 要加密的数据
const data = 'Hello, HMAC!';
// 密钥
const key = 'mysecretkey';
// 创建 HMAC 对象,使用 SHA256 算法
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
// 获取签名
const signature = hmac.digest('hex');
console.log('JavaScript 计算的签名:', signature);</pre>
这里可以想象代码运行后输出结果的截图风格配图,由于无法实际提供截图,你可以自行运行代码查看结果。
5️⃣ 服务端如何验证签名
服务端校验 HMAC 签名的逻辑流程可以分为三步:
请求:客户端将数据和签名一起发送给服务端。
生成签名:服务端使用相同的密钥和接收到的数据重新计算签名。
对比签名:将重新计算的签名与客户端发送的签名进行比较,如果相同,则说明数据没有被篡改,请求是合法的。
下面这张图展示了服务端校验 HMAC 签名的逻辑流程: [图片上传失败...(image-273fd6-1758436324760)]
6️⃣ HMAC 和普通 Hash 的区别
HMAC 和普通哈希的主要区别在于是否使用了密钥。普通哈希是对数据进行单向转换,生成一个固定长度的哈希值,但无法保证数据的完整性和真实性。而 HMAC 使用了一个密钥,使得生成的签名更加安全,只有拥有相同密钥的人才能生成相同的签名。
下面是一个表格对比 HMAC 和普通哈希的区别:
比较项 | HMAC | 普通 Hash |
---|---|---|
是否使用密钥 | 是 | 否 |
安全性 | 高,可验证数据完整性和真实性 | 低,仅能保证数据单向转换 |
应用场景 | API 签名、数据验证等 | 数据存储、文件校验等 |
下面这张图用锁 vs 链条的意象表达了“带密钥的更安全”: [图片上传失败...(image-73d13f-1758436324760)]
7️⃣ 常见问题答疑(FAQ)
可以用在前端吗?
可以,但需要注意密钥的安全性。在前端使用 HMAC 时,密钥不能暴露在客户端代码中,否则会存在安全风险。一般来说,前端可以使用公钥或临时密钥进行签名,然后在服务端进行验证。
支持哪些哈希算法?
HMAC 可以使用多种哈希算法,如 SHA-1、SHA-256、MD5 等。不同的应用场景可以选择不同的哈希算法,一般建议使用安全性较高的算法,如 SHA-256。
是否会被截获?
虽然 HMAC 可以保证数据的完整性和真实性,但如果密钥被泄露,签名就可能被伪造。因此,保护密钥的安全非常重要。此外,在数据传输过程中,还可以结合其他安全措施,如 HTTPS 协议,来防止数据被截获。
8️⃣ 总结 + 使用建议
总结
HMAC 是一种基于哈希算法的消息认证码,它通过使用密钥和数据进行哈希运算,生成一个签名,用于验证数据的完整性和真实性。HMAC 在很多场景中都有广泛的应用,如 API 接口签名验证、防止数据篡改、登录验证等。
使用建议
选择合适的哈希算法:根据应用场景的安全需求,选择安全性较高的哈希算法,如 SHA-256。
保护密钥安全:密钥是 HMAC 安全的关键,要确保密钥不被泄露。可以使用安全的方式存储和传输密钥,如使用密钥管理系统。
结合其他安全措施:在实际应用中,HMAC 可以结合其他安全措施,如 HTTPS 协议、访问控制等,来提高系统的安全性。
结语
很多加密方案,结合jsjiami的加密,可以有效的保护网页接口。