概述
本文主要为您介绍移动推送签名认证方法。
采用 HMAC-SHA256 算法,根据 SecretKey 生产签名信息。通过校验签名进行鉴权,安全性更好,推荐使用。
参数说明
签名生成方式
1. 通过请求时间戳 + AccessId + 请求 body 进行字符拼接,得到原始的待签名字符串:
待签名字符串 = ${TimeStamp} + ${AccessId} + ${请求body}
2. 通过 SecretKey 作为密钥,对原始待签名字符串进行签名,生成得到签名:
Sign = Base64(HMAC_SHA256(SecretKey, 待签名字符串))
HTTP 协议拼装方式
HTTP 协议 header 中 除了通用头部协议外,需要携带当前请求时间戳、 AccessId、 以及签名 Sign 信息,具体参数如下:
Header 中参数 Key | 含义 | 是否必须 |
Sign | 请求签名 | 是 |
AccessId | 应用 ID | 是 |
TimeStamp | 请求时间戳,单位:s(秒) | 是 |
具体 HTTP 请求报文如下:
POST /v3/push/app HTTP/1.1Host: api.tpns.tencent.comContent-Type: application/jsonAccessId: 1500001048TimeStamp: 1565314789Sign: Y2QyMDc3NDY4MmJmNzhiZmRiNDNlMTdkMWQ1ZDU2YjNlNWI3ODlhMTY3MGZjMTUyN2VmNTRjNjVkMmQ3Yjc2ZA=={"audience_type": "account","message": {"title": "test title","content": "test content","android": { "action": {"action_type": 3,"intent": "xgscheme://com.xg.push/notify_detail?param1=xg"}}},"message_type": "notify","account_list": ["5822f0eee44c3625ef0000bb"] }
签名生成示例
1. 生成待拼接签名字符串如下:
待加密字符串=15653147891500001048{"audience_type": "account","message": {"title": "test title","content": "test content","android": { "action": {"action_type": 3,"intent": "xgscheme://com.xg.push/notify_detail?param1=xg"}}},"message_type": "notify","account_list": ["5822f0eee44c3625ef0000bb"] }
说明
待签名字符串中的
${请求body}
和发送数据必须保持一致,包括空格、数据编码等。2. 根据密钥通过 HMAC-SHA256 算法,生成十六进制 hash,其中示例对应
secretKey =1452fcebae9f3115ba794fb0fff2fd73
。hashcode= hmac-sha256(SecretKey, 待签名字符串)得到 hashcode="09f07d2a518a8814e369dcd9534f10b8a29d128531a19adaa28cb247605c1e84"
3. 对 hashcode 进行 base64 编码,得到签名串如下:
得到 Sign=Base64(hashcode)Sign="MDlmMDdkMmE1MThhODgxNGUzNjlkY2Q5NTM0ZjEwYjhhMjlkMTI4NTMxYTE5YWRhYTI4Y2IyNDc2MDVjMWU4NA=="
各语言签名代码示例
#!/usr/bin/env pythonimport hmacimport base64from hashlib import sha256s = '15653147891500001048{"audience_type": "account","message": {"title": "test title","content": "test content","android": { "action": {"action_type": 3,"intent": "xgscheme://com.xg.push/notify_detail?param1=xg"}}},"message_type": "notify","account_list": ["5822f0eee44c3625ef0000bb"] }'key = '1452fcebae9f3115ba794fb0fff2fd73'hashcode = hmac.new(key, s, digestmod=sha256).hexdigest()print base64.b64encode(hashcode)
import hmacimport base64from hashlib import sha256s = '15653147891500001048{"audience_type": "account","message": {"title": "test title","content": "test content","android": { "action": {"action_type": 3,"intent": "xgscheme://com.xg.push/notify_detail?param1=xg"}}},"message_type": "notify","account_list": ["5822f0eee44c3625ef0000bb"] }'key = '1452fcebae9f3115ba794fb0fff2fd73'hashcode = hmac.new(bytes(key, "utf-8"), bytes(s, "utf-8"),digestmod=sha256).hexdigest()print(base64.b64encode(bytes(hashcode, "utf-8")))
package com.tencent.xg;import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Base64;import org.apache.commons.codec.binary.Hex;public class SignTest {public static void main(String[] args) {try {String stringToSign = "15653147891500001048{\\"audience_type\\": \\"account\\",\\"platform\\": \\"android\\",\\"message\\": {\\"title\\": \\"test title\\",\\"content\\": \\"test content\\",\\"android\\": { \\"action\\": {\\"action_type\\": 3,\\"intent\\": \\"xgscheme://com.xg.push/notify_detail?param1=xg\\"}}},\\"message_type\\": \\"notify\\",\\"account_list\\": [\\"5822f0eee44c3625ef0000bb\\"] }";String appSecret = "1452fcebae9f3115ba794fb0fff2fd73";Mac mac;mac = Mac.getInstance("HmacSHA256");mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));byte[] signatureBytes = mac.doFinal(stringToSign.getBytes("UTF-8"));String hexStr = Hex.encodeHexString(signatureBytes);String signature = Base64.encodeBase64String(hexStr.getBytes());System.out.println(signature);} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {e.printStackTrace();}}}
import ("crypto/hmac""crypto/sha256""encoding/base64""encoding/hex""testing")func TestSign(t *testing.T) {requestBody := "15653147891500001048{\\"audience_type\\": \\"account\\",\\"message\\": {\\"title\\": \\"test title\\",\\"content\\": \\"test content\\",\\"android\\": { \\"action\\": {\\"action_type\\": 3,\\"intent\\": \\"xgscheme://com.xg.push/notify_detail?param1=xg\\"}}},\\"message_type\\": \\"notify\\",\\"account_list\\": [\\"5822f0eee44c3625ef0000bb\\"] }"secretKey := "1452fcebae9f3115ba794fb0fff2fd73"h := hmac.New(sha256.New, []byte(secretKey))h.Write([]byte(requestBody))sha := hex.EncodeToString(h.Sum(nil))sign := base64.StdEncoding.EncodeToString([]byte(sha))println(sign)}
using System;using System.Security.Cryptography;using System.Text;namespace tpns_server_sdk_cs{class GenSign {//Main Methodstatic public void Main(String[] args){string reqBody ="{\\"audience_type\\": \\"account\\",\\"message\\": {\\"title\\": \\"test title\\",\\"content\\": \\"test content\\",\\"android\\": { \\"action\\": {\\"action_type\\": 3,\\"intent\\": \\"xgscheme://com.xg.push/notify_detail?param1=xg\\"}}},\\"message_type\\": \\"notify\\",\\"account_list\\": [\\"234\\"] }";string genSign = GenSign.genSign("1621307510", "1500004469", reqBody, "2b1163d904bd5f82dcf82dcf82dc4407");Console.WriteLine(genSign);}public static string HmacSHA256(string key, string data){string hash;Byte[] code = System.Text.Encoding.UTF8.GetBytes(key);using (HMACSHA256 hmac = new HMACSHA256(code)){Byte[] d = System.Text.Encoding.UTF8.GetBytes(data);//Byte[] hmBytes = hmac.ComputeHash(encoder.GetBytes(data));Byte[] hmBytes = hmac.ComputeHash(d);hash = ToHexString(hmBytes);}return hash;}public static string ToHexString(byte[] array){StringBuilder hex = new StringBuilder(array.Length * 2);foreach (byte b in array){hex.AppendFormat("{0:x2}", b);}return hex.ToString();}public static string genSign(string timeStampStr, string accessId, string requestBody, string keySecret){string data = timeStampStr + accessId + requestBody;string hash = HmacSHA256(keySecret, data);string sign = Base64Encode(hash);Console.WriteLine("timeStampStr: " + timeStampStr + " accessId:" + accessId + " requestBody" + requestBody + " keySecret:" + keySecret);return sign;}public static string Base64Encode(string plainText) {var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);return System.Convert.ToBase64String(plainTextBytes);}}}
<?php$accessId = "1500001048";$secretKey = "1452fcebae9f3115ba794fb0fff2fd73";$timeStamp = "1565314789";$requestBody = "{\\"audience_type\\": \\"account\\",\\"message\\": {\\"title\\": \\"test title\\",\\"content\\": \\"test content\\",\\"android\\": { \\"action\\": {\\"action_type\\": 3,\\"intent\\": \\"xgscheme://com.xg.push/notify_detail?param1=xg\\"}}},\\"message_type\\": \\"notify\\",\\"account_list\\": [\\"5822f0eee44c3625ef0000bb\\"] }";$hashData = "{$timeStamp}{$accessId}{$requestBody}";echo "reqBody: " . $hashData . "\\n";//获取 sha256 and hex 结果$hashRes = hash_hmac("sha256", $hashData, $secretKey, false);//进行 base64$sign = base64_encode($hashRes);echo $sign . "\\n";?>