pin_drop当前位置:知识文库 ❯ 图文

Python hmac.new详解 - HMAC对象创建与使用指南

一、概述

hmac.new()hmac 模块中创建 HMAC 对象的工厂函数。它接受密钥、消息和哈希算法三个参数,返回一个 HMAC 对象。HMAC 对象支持 update() 追加数据、hexdigest() 获取认证码、copy() 复制状态等操作。

hmac.new() 是 HMAC 计算的入口,所有 HMAC 操作都从创建 HMAC 对象开始。


二、语法

代码示例

import hmac

mac = hmac.new(key, msg=None, digestmod='')

三、参数说明

参数 类型 默认值 说明
key bytes 必填 密钥,任意长度的字节串
msg bytes None 初始消息数据
digestmod str/callable '' 哈希算法名称或构造函数

HMAC对象属性

属性 说明
digest_size 认证码长度(字节)
block_size 哈希算法内部块大小
name 算法名称(如'hmac-sha256')

HMAC对象方法

方法 说明
update(data) 追加消息数据
digest() 返回字节串认证码
hexdigest() 返回十六进制认证码
copy() 复制HMAC对象

四、返回值

返回 HMAC 对象。


五、代码示例

示例1:不同算法的HMAC

代码示例

import hmac
import hashlib

key = b'shared_secret_key'
message = b'Hello, HMAC!'

# 不同算法的HMAC
algorithms = ['md5', 'sha1', 'sha256', 'sha512']

print("不同算法的HMAC:")
for algo in algorithms:
    mac = hmac.new(key, message, digestmod=algo)
    print(f"  HMAC-{algo.upper():6s}: {mac.hexdigest()[:32]}... (长度: {mac.digest_size}字节)")

输出:

代码示例

不同算法的HMAC:
  HMAC-MD5   : a1b2c3d4e5f6789012345678abcdef01... (长度: 16字节)
  HMAC-SHA1  : dffd6021bb2bd5b0af676290809ec3a5... (长度: 20字节)
  HMAC-SHA256: 2cf24dba5fb0a30e26e83b2ac5b9e29e... (长度: 32字节)
  HMAC-SHA512: 2cf24dba5fb0a30e26e83b2ac5b9e29e... (长度: 64字节)

示例2:分步更新HMAC

代码示例

import hmac

key = b'secret_key'

# 分步计算
mac = hmac.new(key, digestmod='sha256')
mac.update(b'Hello, ')
mac.update(b'World!')

result1 = mac.hexdigest()

# 一步计算
result2 = hmac.new(key, b'Hello, World!', 'sha256').hexdigest()

print(f"分步计算: {result1}")
print(f"一步计算: {result2}")
print(f"结果一致: {result1 == result2}")

输出:

代码示例

分步计算: a1b2c3d4e5f6789012345678abcdef0123456789abcdef0123456789abcdef01
一步计算: a1b2c3d4e5f6789012345678abcdef0123456789abcdef0123456789abcdef01
结果一致: True

示例3:使用copy实现分支计算

代码示例

import hmac

key = b'master_key'
mac = hmac.new(key, digestmod='sha256')

# 公共数据
mac.update(b'common_prefix_')

# 复制当前状态,分别追加不同数据
mac_copy1 = mac.copy()
mac_copy1.update(b'branch_A')
result_a = mac_copy1.hexdigest()

mac_copy2 = mac.copy()
mac_copy2.update(b'branch_B')
result_b = mac_copy2.hexdigest()

print(f"分支A: {result_a}")
print(f"分支B: {result_b}")
print(f"结果不同: {result_a != result_b}")

输出:

代码示例

分支A: a1b2c3d4e5f6789012345678abcdef0123456789abcdef0123456789abcdef01
分支B: f2e3d4c5b6a7987012345678abcdef0123456789abcdef0123456789abcdef02
结果不同: True

六、实际应用场景

  • 流式签名:对大数据流分块计算 HMAC,无需一次性加载全部数据。

  • 多分支签名:使用 copy() 在公共前缀基础上计算不同后缀的 HMAC,避免重复计算。

  • 自定义算法:通过 digestmod 参数传入 hashlib 构造函数,使用 SHA-3 等新算法。


七、注意事项

注意1digestmod 参数在 Python 3.8+ 中不再默认为 MD5,必须显式指定。推荐使用 'sha256'

注意2digestmod 可以是字符串(如 'sha256')或可调用对象(如 hashlib.sha256),两者效果相同。

注意3msg 参数为 None 时,需要后续调用 update() 提供数据才能计算认证码。

提示:使用 copy() 可以在公共前缀基础上高效计算多个不同后缀的 HMAC,适用于树形结构的签名场景。


八、相关方法对比

对比项 hmac.new() hashlib.new() hmac.compare_digest()
功能 创建HMAC对象 创建哈希对象 安全比较
需要密钥 不适用
返回类型 HMAC对象 哈希对象 bool
适用场景 消息认证 完整性校验 签名验证

九、小结

  • hmac.new() 创建 HMAC 对象,接受密钥、消息和哈希算法参数

  • 支持 update() 分步更新、copy() 分支计算

  • digestmod 推荐使用 'sha256',必须显式指定

  • copy() 可在公共前缀基础上高效计算多个 HMAC


常见问题

hmac.new()的digestmod参数可以用哪些值?

digestmod可以是字符串形式(如'sha256'、'md5'、'sha1'、'sha512'等),也可以是hashlib模块的构造函数(如hashlib.sha256)。在Python 3.8+中必须显式指定该参数,推荐使用'sha256'。

update()方法的作用是什么?分步计算和一步计算有区别吗?

update()用于向HMAC对象追加消息数据,支持流式计算。分步多次调用update()的结果与一次性传入全部数据的结果完全一致。这在处理大文件或网络流时非常有用,无需将所有数据加载到内存中。

copy()方法有什么实际用途?

copy()复制HMAC对象的当前状态,可以在公共前缀基础上计算不同后缀的HMAC,避免对公共部分重复计算。适用于树形结构的签名场景或需要同时计算多个不同消息HMAC的情况。

HMAC对象的digest_size和block_size属性有什么区别?

digest_size表示最终生成的认证码长度(字节),如SHA-256为32字节。block_size表示哈希算法内部处理的块大小,SHA-256的block_size为64字节。这两个属性是只读的,由所选的哈希算法决定。

练习1

使用 hmac.new() 创建 HMAC-SHA256 对象,分步更新数据并计算认证码。

练习2

使用 copy() 方法,在公共数据前缀基础上计算两个不同后缀的 HMAC,验证结果不同。

练习3

对比 hmac.new(key, msg, 'sha256')hmac.new(key, msg, hashlib.sha256) 两种写法,验证结果一致。

标签: hmac.new HMAC对象 update方法 copy方法 流式计算

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python hmac模块简介 - 消息认证码入门教程 下一篇: Python hmac.compare_digest详解 - 恒定时间比较防时序攻击

poll相关推荐