更新时间:2024-09-10 01:49:13
发送 API 调用请求时,API 网关 要求应用提供签名(Sign)进行身份验证。本文介绍如何构建 API 签名。
API 网关采用 HMAC SHA256 方法创建摘要。您可以通过 Postman 软件,自行校验 API 请求中 sign
的加密结果。关于校验方法,查看 验证签名结果。
为了提供更安全的服务,API 网关对签名算法进行了升级。在 2021 年 6 月 30 日之后创建的新项目仅支持使用新算法验签。2021 年 6 月 30 日前创建的项目仍可使用旧版签名机制。但是,基于信息安全考虑,建议您修改为新的签名算法。
适用范围:获取令牌和刷新令牌 API。
签名算法:
sign = HMAC-SHA256(client_id + t + nonce + stringToSign, secret).toUpperCase()
算法逻辑:
nonce
为您生成的 UUID,结合时间戳防重复,nonce
为非必填字段。stringToSign
为签名字符串。client_id
与当前请求的 13 位标准时间戳(t
)、nonce
、stringToSign
拼接成字符串。secret
进行哈希摘要,得到新的字符串。适用范围:令牌管理接口以外的其他 API。
签名算法:
str = client_id + access_token + t + nonce + stringToSign
sign = HMAC-SHA256(str, secret).toUpperCase()
算法逻辑:
nonce
为您生成的 UUID,结合时间戳防重复,nonce
为非必填字段。stringToSign
为签名字符串。client_id
、access_token
、当前请求的 13 位标准时间戳(t
)、nonce
、stringToSign
拼接成字符串。secret
进行哈希摘要,得到新的字符串。组成部分:
String stringToSign=
HTTPMethod + "\n" +
Content-SHA256 + "\n" +
Headers + "\n" +
Url
签名字符串字段:
HTTPMethod
为全大写,如 POST
、PUT
等。
Content-SHA256
是指请求 Body 的 SHA256 值。只有当 Body 非 Form 表单时,才计算 SHA256,计算方式如下:
String content-SHA256 = SHA256(bodyStream.getbytes("UTF-8")); //bodyStream 为字节数组
当 Body 为空时,也会进行加密,加密结果为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
。
Headers
是指参与签名计算的 Header 的字段(Key)和字段取值(Value)拼接的字符串。
您需要将参与签名的 Header 的字段拼接到一起,用半角冒号(:
)分隔,作为 Signature-Headers
的值。Header 格式如下:
client_id:xxx
Signature-Headers : Key1:Key2
Key1:xxx
Key2:xxx
key3:xxx (不会加到签名计算中)
nonce:xxx
·····
如果只计算出现在 Signature-Headers
里面的 Key,则如下所示:
String Headers =
HeaderKey1 + ":" + HeaderValue1 + "\n" +
HeaderKey2 + ":" + HeaderValue2 + "\n" +
...
HeaderKeyN + ":" + HeaderValueN + "\n"
URL
指 Path、Query、Body 中 Form 参数。
对 Query+Form 参数按照字典对 Key 进行排序后,按照如下方法拼接,如果 Query 或 Form 参数为空,则 URL=Path,不需要添加?
。
String url =
Path +
"?" +
Key1 + "=" + Value1 +
"&" + Key2 + "=" + Value2 +
"&" + Key3 +
...
"&" + KeyN + "=" + ValueN
以 获取用户列表 API 为例,schema
参数为 apps
,无 body 参数。
接口调用请求头(Request Header)参数,请参考 请求结构。
参数 | 取值 |
---|---|
URL | /v2.0/apps/schema/users |
method | GET |
client_id | 1KAD46OrT9HafiKdsXeg |
secret | 4OHBOnWOqaEC1mWXOpVL3yV50s0qGSRC |
t | 1588925778000 |
access_token | 3f4eda2bdec17232f67c0b188af3eec1 |
sign_method | HMAC-SHA256 说明:签名的摘要算法,请求头必须添加。 |
nonce | 5138cc3a9033d69856923fd07b491173 |
Signature-Headers | area_id:call_id |
area_id (开发者自定义) | 29a33e8796834b1efa6 |
call_id (开发者自定义) | 8afdb70ab2ed11eb85290242ac130003 |
page_no | 1 |
page_size | 50 |
拼接 stringToSign
签名字符串。
stringToSign=GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v1.0/token?grant_type=1
拼接待签名字符串。
1KAD46OrT9HafiKdsXeg15889257780005138cc3a9033d69856923fd07b491173GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v1.0/token?grant_type=1
通过哈希摘要获得新字符。
哈希摘要:
HMAC-SHA256(1KAD46OrT9HafiKdsXeg15889257780005138cc3a9033d69856923fd07b491173GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v1.0/token?grant_type=1,4OHBOnWOqaEC1mWXOpVL3yV50s0qGSRC)
新字符:
9e48a3e93b302eeecc803c7241985d0a34eb944f40fb573c7b5c2a82158af13e
转换为大写。
9E48A3E93B302EEECC803C7241985D0A34EB944F40FB573C7B5C2A82158AF13E
拼接 stringToSign
签名字符串。
stringToSign=GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v2.0/apps/schema/users?page_no=1&page_size=50
拼接待签名字符串。
1KAD46OrT9HafiKdsXeg3f4eda2bdec17232f67c0b188af3eec115889257780005138cc3a9033d69856923fd07b491173GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v2.0/apps/schema/users?page_no=1&page_size=50
通过哈希摘要获得新字符。
哈希摘要:
HMAC-SHA256(1KAD46OrT9HafiKdsXeg3f4eda2bdec17232f67c0b188af3eec115889257780005138cc3a9033d69856923fd07b491173GET
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
area_id:29a33e8796834b1efa6
call_id:8afdb70ab2ed11eb85290242ac130003
/v2.0/apps/schema/users?page_no=1&page_size=50,4OHBOnWOqaEC1mWXOpVL3yV50s0qGSRC)
新字符:
ae4481c692aa80b25f3a7e12c3a5fd9bbf6251539dd78e565a1a72a508a88784
转换为大写。
AE4481C692AA80B25F3A7E12C3A5FD9BBF6251539DD78E565A1A72A508A88784
单击下载 Java 代码示例。
单击下载 Go 代码示例。
单击下载 Node.js 代码示例。
/**
Run the code online with this jsfiddle. Dependent upon an open source js library calledhttp://code.google.com/p/crypto-js/.
**/
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/hmac-sha256.min.js"></script>
<script>
var hash = CryptoJS.HmacSHA256("Message", "secret");
var hashInBase64 = hash.toString().toUpperCase();
document.write(hashInBase64);
</script>
/**
PHP has built in methods for hash_hmac (PHP 5) and base64_encode (PHP 4, PHP 5) resulting in no outside dependencies. Say what you want about PHP but they have the cleanest code for this example.
**/
$s = strtoupper(hash_hmac("sha256", "Message", 'secret'));
echo var_dump($s);
using System;
using System.Security.Cryptography;
namespace Test
{
public class MyHmac
{
public static string Encrypt(string message, string secret)
{
secret = secret ?? "";
var encoding = new System.Text.UTF8Encoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < hashmessage.Length; i++)
{
builder.Append(hashmessage[i].ToString("x2"));
}
return builder.ToString().ToUpper();
}
}
}
}
本地开发时,可用基于 Postman 软件预先查看加密后的签名结果。查询方法请参考 验证签名结果。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈