华为云、阿里云、AWS签名机制详解! AK/SK + HMAC-SHA256 签名鉴权!

今天在做机动车重点库是遇到了一个新的鉴权模式,本质上和:

  • 华为云
  • 阿里云
  • AWS

那套签名机制类似。 总体做下来感觉比较有记录意义,现在分享出来给大家做参考。

目录

一、需要做的事情

二、规则

三、示例

四、真正参与签名的数据

[body 要按 key 排序](#body 要按 key 排序)

五、最终签名原文

[六、Java 完整工具类(直接能用)](#六、Java 完整工具类(直接能用))

[Hmac 工具类](#Hmac 工具类)

七、调用示例

请求头

八、最容易踩坑的地方(你一定会遇到)

[1 body字段顺序](#1 body字段顺序)

[2 path 不是完整 URL](#2 path 不是完整 URL)

[3 POST 必须大写](#3 POST 必须大写)

[4 \n 换行问题](#4 \n 换行问题)

[5 body 不是 JSON](#5 body 不是 JSON)

[6 Content-Type](#6 Content-Type)

九、政务系统现状


一、需要做的事情

核心只有三步:

步骤 内容
1 组装签名字符串
2 用 SK 做 HmacSHA256
3 Base64 编码后放 header

二、规则

签名原文格式:

复制代码
HTTP_METHOD
PATH
AK
TIMESTAMP
BODY排序后的字段拼接

注意:

复制代码
是直接拼接
不是 JSON
不是 &
不是 urlencode

三、示例

请求:

复制代码
POST
"****/****/test"

AK:

复制代码
appkey92f6

时间戳:

复制代码
1685443083119

body:

复制代码
{
  "authType":1,
  "lend_time":"2023-05-19 23:00:00",
  "org_code":"51013",
  "org_code_all":"510",
  "pageNo":1,
  "pageSize":5,
  "start_time":"2023-05-19 00:00:00"
}

四、真正参与签名的数据

注意:

body 要按 key 排序

变成:

复制代码
authType1
lend_time2023-05-19 23:00:00
org_code51013
org_code_all510
pageNo1
pageSize5
start_time2023-05-19 00:00:00

五、最终签名原文

复制代码
POST
****/***/test
appkey92f6
1685443083119
authType1
lend_time2023-05-19 23:00:00
org_code51013
org_code_all510
pageNo1
pageSize5
start_time2023-05-19 00:00:00

注意:

文档里的 \n 是换行


六、Java 完整工具类(直接能用)

Hmac 工具类

复制代码
import com.alibaba.fastjson.JSON;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;

public class HmacSignUtil {

    /**
     * 生成签名
     */
    public static String sign(
            String method,
            String path,
            String ak,
            String sk,
            String timestamp,
            Map<String, Object> body
    ) throws Exception {

        // 1 body按key排序
        TreeMap<String, Object> sortedMap = new TreeMap<>(body);

        // 2 拼接body
        StringBuilder bodyBuilder = new StringBuilder();

        for (Map.Entry<String, Object> entry : sortedMap.entrySet()) {
            bodyBuilder.append(entry.getKey())
                    .append(entry.getValue());
        }

        // 3 拼接签名原文
        String signStr =
                method.toUpperCase() + "\n"
                        + path + "\n"
                        + ak + "\n"
                        + timestamp + "\n"
                        + bodyBuilder;

        System.out.println("签名原文:");
        System.out.println(signStr);

        // 4 HmacSHA256
        Mac mac = Mac.getInstance("HmacSHA256");

        SecretKeySpec secretKeySpec =
                new SecretKeySpec(sk.getBytes(StandardCharsets.UTF_8),
                        "HmacSHA256");

        mac.init(secretKeySpec);

        byte[] bytes =
                mac.doFinal(signStr.getBytes(StandardCharsets.UTF_8));

        // 5 Base64
        return Base64.getEncoder().encodeToString(bytes);
    }
}

七、调用示例

复制代码
Map<String, Object> body = new HashMap<>();

body.put("authType", 1);
body.put("lend_time", "2023-05-19 23:00:00");
body.put("org_code", "51013");
body.put("org_code_all", "510");
body.put("pageNo", 1);
body.put("pageSize", 5);
body.put("start_time", "2023-05-19 00:00:00");

String ak = "你的AK";
String sk = "你的SK";

String timestamp = String.valueOf(System.currentTimeMillis());

String sign = HmacSignUtil.sign(
        "POST",
        "****/****/test",
        ak,
        sk,
        timestamp,
        body
);

System.out.println(sign);

请求头

然后请求时:

复制代码
headers.add("X-BG-HMAC-SIGNATURE", sign);
headers.add("X-BG-HMAC-ALGORITHM", "HmacSHA256");
headers.add("X-BG-HMAC-ACCESS-KEY", ak);
headers.add("X-BG-DATE-TIME", timestamp);
headers.add("Accept", "*/*");

八、最容易踩坑的地方(你一定会遇到)

1 body字段顺序

必须:

复制代码
按 key 字典序排序

所以:

复制代码
TreeMap

非常关键。


2 path 不是完整 URL

错误:

复制代码
https://xx.com/***/test

正确:

复制代码
"****/****/test"

只取:

复制代码
/*** 后面的内容

3 POST 必须大写

复制代码
POST
GET

4 \n 换行问题

必须:

复制代码
"\n"

不能:

复制代码
System.lineSeparator()

5 body 不是 JSON

很多人会错写:

复制代码
JSON.toJSONString(body)

这是错的。

文档要求:

复制代码
key + value 拼接

6 Content-Type

只有:

复制代码
application/json
application/x-www-form-urlencoded

才参与 body 签名。


九、政务系统现状

鉴权 类型
HMAC 最常见
JWT 常见
OAuth2 平台类
国密 SM2/SM3/SM4 政务高频
RSA 签名 公安常见
相关推荐
小李飞刀李寻欢13 小时前
DeepSeek V3 版本模型结构分析
算法·大模型·deepseek
某不知名網友13 小时前
C++ 七大排序算法完整讲解
java·算法·排序算法
得物技术13 小时前
得物推荐系统诊断 Agent:从 “调接口” 到 “会思考”|AICon 演讲整理
人工智能·算法·架构
Lugas14 小时前
为啥说男生找对象尽量在25岁前找到?
算法
MrZhao40014 小时前
从能跑到可用:一个 Agent Harness 还差哪些工程闭环?
算法
AliCloudROS14 小时前
一次真实录屏:我只说每月别超过 200 块,小程序后端就搭好了
运维·人工智能·云计算
QN1幻化引擎14 小时前
Gravity-Anchored Cognitive Field Architecture: The DalinX V8/V10 Implementation
java·前端·算法
Database_Cool_14 小时前
阿里云 PolarDB-X vs OceanBase 国产分布式数据库深度对比
分布式·阿里云·oceanbase
学计算机的计算基15 小时前
LeetCode 图论四题精讲:BFS、拓扑排序、Trie 树的模板与优化
java·笔记·算法
浩瀚地学15 小时前
【面试算法笔记】0202-链表-基本功能实现
java·经验分享·笔记·算法·面试