HMAC-SHA256 请求签名与验签实践(Python 可直接复用)

news/2025/10/18 16:27:18/文章来源:https://www.cnblogs.com/zhaoyingjie/p/19147193

HMAC-SHA256 请求签名与验签实践(Python 可直接复用)

  • 目标:沉淀一套“能复制即用”的签名/验签规范与代码,解决接口防篡改与防伪造。
  • 关键规则:
    • 待签名串:METHOD + "\n" + Content-MD5 + "\n" + URI_PATH + [ "?" + sorted_query ]
    • Content-MD5:对“原始请求体字节”计算 MD5,hex 小写
    • Query:对 key 做升序排序;同 key 多值取第一个;拼接为 k=v&k2=v2
    • 签名:HMAC-SHA256(secret_bytes, utf8(string_to_sign)) → hex 小写

签名规范

  • 待签名串
    • METHOD 使用大写,如 POST、GET
    • URI_PATH 仅路径,不包含协议/域名/端口,例如 /open_api/query/template
    • 若无 query,省略 ? 部分
  • Content-MD5
    • 取“原始 body 字节”做 MD5;空 body 视为空字节
    • JSON 场景需使用“紧凑 JSON”序列化:separators=(',', ':'), ensure_ascii=False,UTF-8 编码
  • Query 处理
    • key 升序;多值取第一个;不做 URL 编码二次处理(与客户端保持一致)
  • 签名算法
    • HMAC-SHA256,密钥为字节串,输出十六进制小写

可直接复用代码(签名 + 验签)

import hmac
import hashlib
import json
from typing import Dict, Iterable, Tuple, Union, Optional
from urllib.parse import urlparse, parse_qsArgsType = Optional[Dict[str, Union[str, Iterable[str]]]]def _compact_json_bytes(body: Optional[dict]) -> bytes:"""将字典转为“紧凑 JSON”UTF-8字节;None/空字典→空字节"""if not body:return b""raw = json.dumps(body, separators=(",", ":"), ensure_ascii=False)return raw.encode("utf-8")def _sorted_query(args: ArgsType) -> str:"""将 query 参数按 key 升序拼接为 k=v&k2=v2。多值取第一个。None 或空返回 ""。"""if not args:return ""keys = sorted(args.keys())pairs = []for k in keys:v = args[k]if isinstance(v, (list, tuple, set)):v = list(v)[0] if v else ""pairs.append(f"{k}={v}")return "&".join(pairs)def build_string_to_sign(http_method: str,uri_path: str,args: ArgsType,body_bytes: bytes,
) -> Tuple[str, str]:"""构造待签名串与 content_md5(hex 小写)返回: (string_to_sign, content_md5)"""method = http_method.upper()content_md5 = hashlib.md5(body_bytes).hexdigest()qs = _sorted_query(args)uri_and_qs = f"{uri_path}?{qs}" if qs else uri_pathstring_to_sign = f"{method}\n{content_md5}\n{uri_and_qs}"return string_to_sign, content_md5def generate_signature(http_method: str,uri_path: str,args: ArgsType,body: Optional[dict],secret: Union[str, bytes],
) -> Tuple[str, bytes, str]:"""生成签名返回: (signature_hex, body_bytes, string_to_sign)"""if isinstance(secret, str):secret = secret.encode("utf-8")body_bytes = _compact_json_bytes(body)string_to_sign, _ = build_string_to_sign(http_method, uri_path, args, body_bytes)signature = hmac.new(secret, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()return signature, body_bytes, string_to_signdef verify_signature(http_method: str,uri_path: str,args: ArgsType,raw_body_bytes: bytes,provided_signature_hex: str,secret: Union[str, bytes],
) -> bool:"""验签。注意 raw_body_bytes 必须是请求体原始字节(未二次序列化)。"""if isinstance(secret, str):secret = secret.encode("utf-8")string_to_sign, _ = build_string_to_sign(http_method, uri_path, args, raw_body_bytes)expected = hmac.new(secret, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()# 常量时间比较,避免时序侧信道return hmac.compare_digest(provided_signature_hex, expected)

 

 

 

客户端请求示例(Python requests,可直接复制)

import os
import requests
from urllib.parse import urljoin, urlparse, parse_qs# 引入上方的 generate_signature
# from sign_utils import generate_signature

BASE_URL = os.getenv("API_BASE_URL", "https://api.example.com")
URI_PATH = "/open_api/query/template"
URL = urljoin(BASE_URL, URI_PATH)APP_ID = os.getenv("MY_APP_ID", "your_app_id_here")
SECRET = os.getenv("MY_SECRET", "your_secret_here")  # 建议使用环境变量配置

body = {"template_id": "your_template_id"}# 解析 query(若 URL 上还有 ?k=v,可从这里带入参与签名)
args = parse_qs(urlparse(URL).query)sign, body_bytes, string_to_sign = generate_signature(http_method="POST",uri_path=URI_PATH,args=args,body=body,secret=SECRET,
)headers = {"WX-SIGN": sign,"WX-APPID": APP_ID,"Content-Type": "application/json; charset=utf-8",# "WX-DEBUG": "true",  # 调试时可开启
}# 以原始字节发送,确保与签名一致
resp = requests.post(URL, data=body_bytes, headers=headers, timeout=10)
print("status:", resp.status_code)
print("resp:", resp.text)
# 调试输出
print("string_to_sign:", repr(string_to_sign))

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/938716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 年家装管道生产厂家最新推荐排行榜:覆盖云南昆明贵州贵阳四川成都重庆,精选优质 PPR/PVC 管道品牌,解决选购难题

在家装过程中,管道作为水电系统的核心部件,其质量直接决定居住安全与生活舒适度。当前家装管道市场混乱,部分厂商偷工减料,导致管道抗压差、易老化、密封性不足,漏水渗水问题频发,给业主带来巨大财产损失与生活困…

同一设备多账号登录,如何避免消息推送“串门”?

对各应用厂商而言,推送通知消息是App提高用户活跃度和转化率的高性价比营销工具。然而,当一个用户设备登录多个账号时,开发者可能会遇到同一条消息在同一设备的不同账号上重复展示的问题,这不仅降低了消息推送的精…

强合规行业DevOps选型:告别工具拼凑,找到真正适配的国产化DevOps方案

强合规行业DevOps平台选型需“建体系”,传统开源工具组合易陷数据割裂、合规难达标困境。本文对比三款DevOps产品,其中国产DevOps平台契合信创DevOps需求,内置合规卡点与追溯能力,适配国产化环境,助力企业平衡合规…

实用指南:精读 C++20 设计模式:行为型设计模式——观察者模式

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

大疆无人机RTMP推流至LiveNVR实现web页面实时播放与录像回放,并可以转GB28181协议级联推送给上级监控视频管理平台

@目录1、无人机推流转国标2、获取RTMP推流地址2.1、RTMP推流地址格式2.2、推流地址示例2、设备RTMP推流3、配置拉转RTMP3.1、直播流地址格式3.2、直播流地地址示例3.3、通道配置直播流地址4、配置级联到GB28181国标平台…

Character Animator 2025下载安装教程:2D角色动画软件零基础入门,附最新下载安装教程及激活方法

还在找Character Animator 2025怎么下载安装?这份保姆级教程帮你一步到位!不管是做虚拟主播、短视频动画,还是教育课件制作,掌握CH 2025的安装方法是第一步。本文包含详细下载渠道、安装步骤、快捷键及常见问题,看…

2025年彩钢瓦/镀锌板/折弯件/C型钢/Z型钢/压型瓦/楼承板/次檩条厂家推荐排行榜,专业钢结构安装与定制加工实力解析

2025年彩钢瓦/镀锌板/折弯件/C型钢/Z型钢/压型瓦/楼承板/次檩条厂家推荐排行榜,专业钢结构安装与定制加工实力解析随着我国建筑工业化的快速发展,钢结构建筑因其施工周期短、抗震性能好、可回收利用等优势,在工业厂…

2025 年最新金相厂家最新推荐排行榜:涵盖金相磨抛机 / 切割机 / 显微镜 / 抛光机 / 预磨机设备,助力企业精准选择优质品牌

当前材料检测行业持续发展,金相检测作为材料分析核心环节,对石油机械、铁路器材、航空航天等领域的产品质量与安全起着关键作用。随着市场需求升级,金相品牌数量激增,但品牌间技术实力、产品质量和服务水平差距明显…

武汉图核科技

武汉图核科技新的名字 以前的名字是英语单词音译过来的,没有什么具体含义,也不容易看出是做什么的。中国人还是取个中文名好一些,于是想换个名字,要言简意赅,简单好记。不擅长取名,找AI来帮忙:一眼相中了图核科…

maven的概述以及在mac安装部署

maven的概述以及在mac安装部署pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

完整教程:display ospf peer 概念及题目

完整教程:display ospf peer 概念及题目pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "M…

Python 列表切片赋值教程:掌握 “移花接木” 式列表修改技巧

Python 列表切片赋值教程:掌握 “移花接木” 式列表修改技巧$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");列表_切片赋值_slice_assignment_嫁接 回忆上次…

2025中国开发者必看:主流代码托管平台本土化能力深度测评

2025中国开发者必看:主流代码托管平台本土化能力深度测评 在数字化转型加速推进的当下,代码托管平台已成为软件开发团队不可或缺的基础设施。随着国内开发者群体的快速扩张,对代码托管服务的本土化需求也日益凸显。…

开源数据采集工具 logstash(收集日志)/telegraf(收集指标)

Telegraf 是一个用 Go 编写的代理程序,是收集和报告指标和数据的代理。可收集系统和服务的统计数据,并写入到 InfluxDB 数据库。Telegraf 具有内存占用小的特点,通过插件系统开发人员可轻松添加支持其他服务的扩展。…

2025年粉末冶金制品厂家推荐排行榜,粉末冶金零件,金属注射成形,结构件,齿轮,轴承公司最新精选

2025年粉末冶金制品厂家推荐排行榜:粉末冶金零件、金属注射成形、结构件、齿轮、轴承公司最新精选行业背景与发展趋势粉末冶金技术作为现代制造业的核心工艺之一,在汽车、家电、机械装备等领域发挥着越来越重要的作用…

多模态大语言模型LISA - 详解

多模态大语言模型LISA - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

2025 年升降平台车厂家最新推荐口碑排行榜:覆盖多类型产品,聚焦实力厂家,为企业选购提供权威参考剪叉式/手动液压/电动液压升降平台车厂家推荐

在工业生产、仓储物流等领域,升降平台车是不可或缺的关键设备,其质量与性能直接关系到企业运营效率与生产安全。当前市场上,升降平台车品牌繁杂,部分厂家技术落后、工艺不规范、售后不完善,导致企业选购时面临诸多…

供应商图纸协同是什么?主要有哪几个核心原则?

供应商图纸协同是确保制造业供应链高效运作的基础。它不仅涉及图纸和数据的安全传递,也需要关注信息的准确性和及时性。企业通过建立数字平台,可以统一管理图纸及相关文件,加快信息流转。这一过程强调了沟通的重要性…

「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)

「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)如果您需要支持Java EE 5中引入的简化基于注释的POJO编程模型,那么EJB开发工具就是您的正确选择。在此您将了解到:EJB开发工具和EJB项目 持久性支持和EJB项目…

2025 年堆高车厂家最新推荐排行榜:聚焦专利技术、华为等大牌合作案例及国内优质品牌解析手动液压/手动液压/卷筒/油桶堆高车厂家推荐

当前,仓储物流与生产制造行业对堆高车的需求持续攀升,但其市场供给呈现 “质量参差、选型复杂” 的态势。一方面,部分厂家缺乏核心技术,产品故障率高、维护成本高,难以适配高强度作业;另一方面,企业采购时易受低…