跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言java算法

HMAC-SHA1 算法详解

HMAC-SHA1 算法原理、流程及安全性分析,提供 Java 和 Python 代码实现。涵盖密钥处理、哈希计算步骤、API 签名应用及重放攻击防御建议。指出 SHA1 碰撞风险,推荐新系统使用 HMAC-SHA256。

SparkGeek发布于 2026/3/26更新于 2026/5/2524 浏览
HMAC-SHA1 算法详解

1. HMAC-SHA1 是什么?

HMAC(Hash-based Message Authentication Code,基于哈希的消息认证码)是一种消息认证算法。它结合了哈希函数(如 SHA1)和密钥,用于验证消息的完整性和真实性。

HMAC-SHA1 就是以 SHA1 为哈希函数的 HMAC 算法。


2. HMAC 原理

HMAC 的核心思想是:

用一个密钥和哈希函数,对消息进行两次哈希,得到一个消息认证码。

具体公式如下:

HMAC(K, M) = H((K' ⊕ opad) || H((K' ⊕ ipad) || M)) 
  • K:密钥
  • M:消息
  • H:哈希函数(这里是 SHA1)
  • K':密钥 K,如果长度不足 block size(SHA1 的 block size 为 64 字节),则补零;如果超出则先哈希再补零
  • opad:外部填充字节(0x5c 重复 64 次)
  • ipad:内部填充字节(0x36 重复 64 次)
  • ⊕:按位异或
  • ||:拼接
步骤简述
  1. 对密钥 K 进行预处理,得到 K'(长度为 block size)
  2. K' 与 ipad 进行异或,拼接消息 M,做一次哈希
  3. K' 与 opad 进行异或,拼接上一步哈希结果,再做一次哈希
  4. 最终得到 HMAC 值

3. HMAC-SHA1 算法流程

详细步骤:

  1. 密钥处理
    • 如果密钥长度 > 64 字节,先用 SHA1 哈希一次
    • 如果密钥长度 < 64 字节,末尾补零到 64 字节
  2. 计算 K' ⊕ ipad
    • ipad = 0x36 * 64
  3. 计算 K' ⊕ opad
    • opad = 0x5c * 64
  4. 第一轮哈希
    • 先将 (K' ⊕ ipad) 和消息 M 拼接
    • 用 SHA1 哈希,得到结果 H1
  5. 第二轮哈希
    • 将 (K' ⊕ opad) 和 H1 拼接
    • 用 SHA1 哈希,得到最终 HMAC 值

4. Java HMAC-SHA1 实现

Java 标准库 javax.crypto.Mac 和 javax.crypto.spec.SecretKeySpec 就可以实现 HMAC-SHA1。

4.1 生成 HMAC-SHA1 签名
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

   {
    
      [] hmacSHA1([] key, [] message)  Exception {
            (key, );
           Mac.getInstance();
        mac.init(signingKey);
         mac.doFinal(message);
    }

    
      String   Exception {
        [] hmac = hmacSHA1(key.getBytes(), message.getBytes());
         Base64.getEncoder().encodeToString(hmac);
    }

    
         Exception {
           hmacSHA1Base64(key, message);
        
         MessageDigest.isEqual(expected.getBytes(), signatureBase64.getBytes());
    }

    
         Exception {
           ;
           ;
           hmacSHA1Base64(key, message);
        System.out.println( + signature);
        
           verify(key, message, signature);
        System.out.println( + valid);
    }
}
public
class
HmacSHA1Util
/** * 生成 HMAC-SHA1 签名 * @param key 密钥(字节数组) * @param message 消息内容(字节数组) * @return 签名结果(字节数组) * @throws Exception */
public
static
byte
byte
byte
throws
SecretKeySpec
signingKey
=
new
SecretKeySpec
"HmacSHA1"
Mac
mac
=
"HmacSHA1"
return
/** * 生成 HMAC-SHA1 签名,并返回 Base64 编码 * @param key 密钥 * @param message 消息内容 * @return 签名结果(Base64 字符串) * @throws Exception */
public
static
hmacSHA1Base64
(String key, String message)
throws
byte
"UTF-8"
"UTF-8"
return
/** * 验证签名 */
public
static
boolean
verify
(String key, String message, String signatureBase64)
throws
String
expected
=
// 防止时序攻击,建议用 MessageDigest.isEqual
return
"UTF-8"
"UTF-8"
// 示例
public
static
void
main
(String[] args)
throws
String
key
=
"secret_key"
String
message
=
"hello world"
String
signature
=
"HMAC-SHA1 签名 (Base64): "
// 验证
boolean
valid
=
"验证结果:"
4.2 说明
  • key.getBytes("UTF-8") 和 message.getBytes("UTF-8") 用于将字符串转为字节数组。
  • 签名结果通常以 Base64 或 Hex 编码输出,便于存储和传输。
  • 验证时,推荐使用 MessageDigest.isEqual 避免时序攻击。
4.3 依赖

本示例仅用到 Java 标准库,无需额外依赖。

4.4 结果示例

输出示例:

HMAC-SHA1 签名 (Base64): 2jmj7l5rSw0yVb/vlWAYkK/YBwk=
验证结果:true
4.5 进阶建议
  • 如果需要 Hex 编码,可以用 Apache Commons Codec 的 Hex.encodeHexString。
  • 如果用于接口签名,建议在消息中加入时间戳、随机数等防止重放攻击。

5. 代码实现(Python)

import hashlib

def hmac_sha1(key: bytes, message: bytes) -> bytes:
    block_size = 64  # SHA1 block size
    # 1. 密钥处理
    if len(key) > block_size:
        key = hashlib.sha1(key).digest()
    key = key.ljust(block_size, b'\x00')
    # 2. ipad 和 opad
    ipad = bytes([0x36] * block_size)
    opad = bytes([0x5c] * block_size)
    # 3. 第一轮哈希
    inner = hashlib.sha1(bytes([a ^ b for a, b in zip(key, ipad)]) + message).digest()
    # 4. 第二轮哈希
    hmac = hashlib.sha1(bytes([a ^ b for a, b in zip(key, opad)]) + inner).digest()
    return hmac

# 示例
key = b'secret_key'
message = b'hello world'
hmac_value = hmac_sha1(key, message)
print(hmac_value.hex())

注意:实际项目中建议直接用 Python 标准库 hmac:

import hmac
import hashlib

key = b'secret_key'
message = b'hello world'
hmac_value = hmac.new(key, message, hashlib.sha1).hexdigest()
print(hmac_value)

6. 应用场景

  • API 签名认证:如微信、支付宝等接口常用 HMAC-SHA1 或 HMAC-SHA256
  • 消息完整性校验:防止消息被篡改
  • Token 生成与验证:如 JWT 的签名部分
  • 文件完整性验证:如云存储上传时的校验

7. 安全性分析

  • HMAC-SHA1 比直接用 SHA1 安全得多,能抵抗长度扩展攻击
  • 只要密钥足够安全,HMAC-SHA1 在实际应用中仍较安全
  • 但 SHA1 已被证明存在碰撞风险,强安全场景建议用 HMAC-SHA256 或更高版本
  • HMAC-SHA1 仍在很多旧系统中广泛使用

8. HMAC-SHA1 的安全性细节

8.1 为什么 HMAC 比单纯哈希安全?
  • 长度扩展攻击防御:
    普通哈希(如 SHA1)容易受到长度扩展攻击(Length Extension Attack),即攻击者可以在已知哈希值的情况下,构造新的数据和哈希值,使服务器误判数据完整性。HMAC 的双层哈希结构有效防止了此类攻击。
  • 密钥保护:
    HMAC 依赖密钥,只有持有密钥的一方才能生成或验证消息认证码(MAC),防止伪造。
8.2 SHA1 的安全风险
  • SHA1 已被发现存在碰撞攻击(即不同消息可产生相同哈希值),理论上会降低安全性。但 HMAC 的结构能一定程度上缓解这一问题。
  • 尽管如此,新系统建议优先使用 HMAC-SHA256、HMAC-SHA512 等更安全的哈希函数。

9. 与其他 HMAC 算法对比

算法哈希长度安全性性能
HMAC-MD5128 位较低快
HMAC-SHA1160 位中等快
HMAC-SHA256256 位高较快
HMAC-SHA512512 位很高较慢
HMAC-SM3256 位高(国密)较快

建议:

  • 老系统兼容性需求可用 HMAC-SHA1
  • 新系统推荐 HMAC-SHA256 及以上

10. 工程实践建议

10.1 密钥管理
  • 密钥必须随机、安全生成,不应硬编码于代码中
  • 密钥长度至少 128 位(16 字节),推荐 256 位(32 字节)及以上
  • 密钥应妥善保存于安全设备或密钥管理系统(如 KMS)
10.2 消息格式
  • HMAC 计算时,消息内容必须严格一致(如 JSON 字符串需规范化)
  • 常见做法:HMAC(key, timestamp + nonce + body),防止重放攻击
10.3 签名与验证流程
  1. 发送方用密钥对消息计算 HMAC-SHA1,附在消息中
  2. 接收方用同样密钥对收到的消息计算 HMAC-SHA1,与附带值比对
  3. 一致则通过,不一致则拒绝
10.4 代码示例(API 签名)
import hmac
import hashlib

def generate_signature(key, message):
    return hmac.new(key, message, hashlib.sha1).hexdigest()

def verify_signature(key, message, signature):
    expected = generate_signature(key, message)
    return hmac.compare_digest(expected, signature)

# 示例
key = b'supersecret123'
message = b'user_id=1001&amount=500&timestamp=1718000000'
signature = generate_signature(key, message)
print('签名:', signature)
# 验证
print('验证结果:', verify_signature(key, message, signature))

11. HMAC-SHA1 的应用场景举例

  • 云存储授权:如 AWS S3 的签名机制
  • 支付接口防篡改:如支付宝/微信支付
  • JWT Token 签名:JWT 默认支持 HMAC-SHA256,但兼容 HMAC-SHA1
  • 消息队列认证:如 RabbitMQ、Kafka 的安全通信

12. 常见问题与注意事项

  • 密钥泄露风险:一旦密钥泄露,认证机制失效
  • 消息编码一致性:签名前后消息格式必须一致,避免因编码差异导致认证失败
  • 时间戳/随机数:推荐在消息中加入时间戳和 nonce,防止重放攻击

13. 总结

  • HMAC-SHA1 是一种经典的消息认证算法,安全性高于单纯哈希
  • 但 SHA1 已不推荐用于新项目,建议升级为 HMAC-SHA256
  • 实际应用中注意密钥管理、消息格式规范、签名验证流程

目录

  1. 1. HMAC-SHA1 是什么?
  2. 2. HMAC 原理
  3. 步骤简述
  4. 3. HMAC-SHA1 算法流程
  5. 4. Java HMAC-SHA1 实现
  6. 4.1 生成 HMAC-SHA1 签名
  7. 4.2 说明
  8. 4.3 依赖
  9. 4.4 结果示例
  10. 4.5 进阶建议
  11. 5. 代码实现(Python)
  12. 示例
  13. 6. 应用场景
  14. 7. 安全性分析
  15. 8. HMAC-SHA1 的安全性细节
  16. 8.1 为什么 HMAC 比单纯哈希安全?
  17. 8.2 SHA1 的安全风险
  18. 9. 与其他 HMAC 算法对比
  19. 10. 工程实践建议
  20. 10.1 密钥管理
  21. 10.2 消息格式
  22. 10.3 签名与验证流程
  23. 10.4 代码示例(API 签名)
  24. 示例
  25. 验证
  26. 11. HMAC-SHA1 的应用场景举例
  27. 12. 常见问题与注意事项
  28. 13. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Java Swing 滚动面板 JScrollPane 使用示例
  • OpenClaw 在 Linux 下配置本地 Ollama 实战指南
  • Vivado 项目 Git 版本管理实战指南
  • 前端首屏加载优化落地清单与实操指南
  • Milvus 实战:Attu 可视化安装与 Python 整合指南
  • XLeRobot VR 控制系统搭建与 Quest3 实操指南
  • IDEA 三大 AI 编程插件实测:Copilot、TRAE 与灵码对比
  • VS Code 中 GitHub Copilot 插件无法加载模型的排查与修复
  • VSCode 中配置 Copilot MCP 快速上手指南
  • AIGC 个性化与定制化内容生成:技术原理与应用
  • C++11 function 与 bind 包装器详解
  • C++ 继承详解:语法、陷阱与最佳实践
  • ClawX:基于 OpenClaw 的桌面版 AI 助手部署指南
  • Python AI 三剑客:文档总结、代码生成与资料检索
  • Spring AI 入门实战:从环境配置到 RAG 应用构建
  • Spring Boot 集成 MyBatis 操作数据库详解
  • Collabora Online 开源协作办公套件快速部署指南
  • Git 多人协作开发流程与最佳实践
  • FastGPT 集成 MCP 协议构建工具增强型智能体
  • Neo4j 图数据库核心概念与在线控制台使用指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online