输入内容
输入要计算HMAC的消息内容和密钥
0 字符
0 字符
HMAC结果
HMAC计算后的结果
等待计算...
等待计算...
使用算法:
-
输出长度:
-
代码示例
以下是在不同编程语言中实现HMAC的代码示例:
JavaScript HMAC实现
// 使用 Web Crypto API 实现 HMAC
async function hmacSHA256(message, key) {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const messageData = encoder.encode(message);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const signature = await crypto.subtle.sign(
'HMAC',
cryptoKey,
messageData
);
// 转换为十六进制
const hashArray = Array.from(new Uint8Array(signature));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
// HMAC SHA512
async function hmacSHA512(message, key) {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const messageData = encoder.encode(message);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: 'SHA-512' },
false,
['sign']
);
const signature = await crypto.subtle.sign(
'HMAC',
cryptoKey,
messageData
);
const hashArray = Array.from(new Uint8Array(signature));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
// 使用示例
(async () => {
const message = 'Hello, World!';
const key = 'secret-key';
const hmac256 = await hmacSHA256(message, key);
const hmac512 = await hmacSHA512(message, key);
console.log('HMAC-SHA256:', hmac256);
console.log('HMAC-SHA512:', hmac512);
})();
Python HMAC实现
import hmac
import hashlib
import base64
# HMAC-SHA256
def hmac_sha256(message, key):
return hmac.new(
key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).hexdigest()
# HMAC-SHA512
def hmac_sha512(message, key):
return hmac.new(
key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha512
).hexdigest()
# HMAC-SHA1
def hmac_sha1(message, key):
return hmac.new(
key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha1
).hexdigest()
# HMAC-MD5
def hmac_md5(message, key):
return hmac.new(
key.encode('utf-8'),
message.encode('utf-8'),
hashlib.md5
).hexdigest()
# HMAC-SHA256 (Base64输出)
def hmac_sha256_base64(message, key):
digest = hmac.new(
key.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).digest()
return base64.b64encode(digest).decode('utf-8')
# 使用示例
if __name__ == '__main__':
message = 'Hello, World!'
key = 'secret-key'
print(f'HMAC-SHA256: {hmac_sha256(message, key)}')
print(f'HMAC-SHA512: {hmac_sha512(message, key)}')
print(f'HMAC-SHA1: {hmac_sha1(message, key)}')
print(f'HMAC-MD5: {hmac_md5(message, key)}')
print(f'HMAC-SHA256 (Base64): {hmac_sha256_base64(message, key)}')
Java HMAC实现
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class HMACUtil {
// HMAC-SHA256
public static String hmacSHA256(String message, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
}
// HMAC-SHA512
public static String hmacSHA512(String message, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA512");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacSHA512"
);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
}
// HMAC-SHA1
public static String hmacSHA1(String message, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacSHA1"
);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
}
// HMAC-MD5
public static String hmacMD5(String message, String key) throws Exception {
Mac mac = Mac.getInstance("HmacMD5");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacMD5"
);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return bytesToHex(hash);
}
// 字节数组转十六进制字符串
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
// Base64编码
public static String hmacSHA256Base64(String message, String key) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}
public static void main(String[] args) throws Exception {
String message = "Hello, World!";
String key = "secret-key";
System.out.println("HMAC-SHA256: " + hmacSHA256(message, key));
System.out.println("HMAC-SHA512: " + hmacSHA512(message, key));
System.out.println("HMAC-SHA1: " + hmacSHA1(message, key));
System.out.println("HMAC-MD5: " + hmacMD5(message, key));
System.out.println("HMAC-SHA256 (Base64): " + hmacSHA256Base64(message, key));
}
}
Node.js HMAC实现
const crypto = require('crypto');
// HMAC-SHA256
function hmacSHA256(message, key) {
return crypto
.createHmac('sha256', key)
.update(message)
.digest('hex');
}
// HMAC-SHA512
function hmacSHA512(message, key) {
return crypto
.createHmac('sha512', key)
.update(message)
.digest('hex');
}
// HMAC-SHA1
function hmacSHA1(message, key) {
return crypto
.createHmac('sha1', key)
.update(message)
.digest('hex');
}
// HMAC-MD5
function hmacMD5(message, key) {
return crypto
.createHmac('md5', key)
.update(message)
.digest('hex');
}
// Base64编码
function hmacSHA256Base64(message, key) {
return crypto
.createHmac('sha256', key)
.update(message)
.digest('base64');
}
// 使用示例
const message = 'Hello, World!';
const key = 'secret-key';
console.log('HMAC-SHA256:', hmacSHA256(message, key));
console.log('HMAC-SHA512:', hmacSHA512(message, key));
console.log('HMAC-SHA1:', hmacSHA1(message, key));
console.log('HMAC-MD5:', hmacMD5(message, key));
console.log('HMAC-SHA256 (Base64):', hmacSHA256Base64(message, key));
什么是HMAC?
HMAC(Hash-based Message Authentication Code)是基于哈希的消息认证码,是一种用于验证消息完整性和真实性的机制。HMAC使用加密哈希函数(如SHA-256、SHA-512)和共享密钥来生成一个固定长度的认证码。
HMAC的工作原理
HMAC的计算过程包括以下步骤:
- 如果密钥长度大于哈希函数的块大小,先对密钥进行哈希
- 如果密钥长度小于块大小,用0填充到块大小
- 将填充后的密钥与内部填充(ipad)进行异或运算
- 将消息追加到结果后面
- 对结果进行哈希
- 将原始密钥与外部填充(opad)进行异或运算
- 将哈希结果追加到后面
- 再次进行哈希,得到最终的HMAC值
HMAC的应用场景
- API签名验证:防止API请求被篡改
- 数据完整性验证:确保数据在传输过程中未被修改
- 身份认证:验证消息发送者的身份
- 防重放攻击:在消息中添加时间戳
- 令牌生成:生成安全的访问令牌
HMAC算法对比
| 算法 | 输出长度 | 安全性 | 推荐用途 |
|---|---|---|---|
| HMAC-SHA256 | 256位 | 高 | 通用场景(推荐) |
| HMAC-SHA512 | 512位 | 极高 | 高安全要求 |
| HMAC-SHA1 | 160位 | 中等 | 兼容性需求 |
| HMAC-MD5 | 128位 | 低 | 不推荐使用 |
常见问题(FAQ)
Q: HMAC和普通哈希有什么区别?
A: HMAC使用密钥,只有拥有密钥的人才能生成和验证HMAC值;普通哈希不需要密钥,任何人都可以计算。HMAC可以同时验证数据的完整性和真实性,而普通哈希只能验证完整性。
Q: 如何选择合适的HMAC算法?
A: 推荐使用HMAC-SHA256作为默认选择。如果对安全性有更高要求,可以使用HMAC-SHA512。HMAC-SHA1和HMAC-MD5由于存在安全问题,不推荐在新的系统中使用。
Q: HMAC密钥应该如何保存?
A: HMAC密钥应该像密码一样安全保存。不要将密钥硬编码在代码中,不要通过不安全的渠道传输。建议使用环境变量、密钥管理服务(如AWS KMS)或硬件安全模块(HSM)来存储密钥。