达实AIoT
文档中心
快速开始
  • 单点登录对接
  • 开放接口对接
  • 领域模型事件对接
  • 私有部署
  • 应用开发指南
  • DASDesign
IoT平台
应用平台
  • 低代码工具
  • 基础服务
  • 系统运维
  • 场景模型
应用
  • 物业管理
  • 数据中心
  • 智慧园区IPS
  • 园区服务
  • 物业管理
  • 场景模型
  • 会议
  • 门禁
  • 停车场
文档中心
快速开始
  • 单点登录对接
  • 开放接口对接
  • 领域模型事件对接
  • 私有部署
  • 应用开发指南
  • DASDesign
IoT平台
应用平台
  • 低代码工具
  • 基础服务
  • 系统运维
  • 场景模型
应用
  • 物业管理
  • 数据中心
  • 智慧园区IPS
  • 园区服务
  • 物业管理
  • 场景模型
  • 会议
  • 门禁
  • 停车场
期待您的声音
  1. 调用方式
  • 快速开始
  • 调用方式
    • 签名机制
    • 错误码
    • 公共参数
    • 响应信息
  • 云端API参考
    • 获取访问凭证令牌
      GET
  • 通讯录
    • 通讯录同步
  1. 调用方式

签名机制

📌
为了防止API调用过程中被黑客恶意篡改,调用API需要携带签名,服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。目前支持的签名算法有两种:MD5(sign_method=md5),HMAC_SHA256(sign_method=hmac-sha256),
签名大体过程如下:
以访问凭证令牌举例:
1) appid=557ADoER&sign_method=hmac_sha256&timestamp=16854380449999 + 秘钥
示例:image.png
2) md5:
appid=557ADoER&sign_method=md5&timestamp=16854380449999 + 秘钥
示例:image.png

Java示例#

以访问凭证令牌举例:
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.util.DigestUtils;

md5加密
String sign = DigestUtils.md5DigestAsHex((appid=557ADoER&sign_method=md5&timestamp=16854380449999密钥).getBytes())

HMAC_SHA_256 加密
String sign = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, 密钥).hmacHex(appid=557ADoER&sign_method=hmac_sha256&timestamp=16854380449999)
签名方法代码示例:

C#示例#


using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace SignUtilsDemo
{
    public class SignUtils
    {
        private const string APPID = "appid";
        private const string TIMESTAMP = "timestamp";
        private const string SIGNATURE = "sign";
        private const string SIGN_METHOD = "sign_method";
        private const string SIGN_TYPE = "sign_type";
        private const string NONCE = "nonce";

        private Dictionary<string, Func<string, string, string>> _handleMap = new Dictionary<string, Func<string, string, string>>()
        {
            { "md5", GetMd5Sign },
            { "hmac_sha256", GetHmacSha256Sign }
        };

        public string SupportSignMethod => string.Join(",", _handleMap.Keys);

        private static string GetMd5Sign(string paramStr, string secret)
        {
            using (var md5 = MD5.Create())
            {
                var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(paramStr + secret));
                return BitConverter.ToString(bytes).Replace("-", "").ToLower();
            }
        }

        private static string GetHmacSha256Sign(string paramStr, string secret)
        {
            using (var hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
            {
                var bytes = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(paramStr));
                return BitConverter.ToString(bytes).Replace("-", "").ToLower();
            }
        }

        private string GenerateSign(string body, Dictionary<string, string> parameters, string appSecret, Func<string, string, string> signMethodHandle)
        {
            var sortedParams = parameters.OrderBy(p => p.Key, StringComparer.Ordinal);
            var paramStr = string.Join("&", sortedParams.Select(p => $"{p.Key}={p.Value}"));

            var sb = new StringBuilder();
            if (!string.IsNullOrWhiteSpace(body))
            {
                sb.Append($"body={body}&");
            }
            sb.Append(paramStr);
            var str = sb.ToString();
            return signMethodHandle(str, appSecret);
        }

        public string Sign(Dictionary<string, string> parameters, string signMethodType, string appSecret, object bodyObject)
        {
            if (!_handleMap.TryGetValue(signMethodType, out var signMethodHandle))
            {
                throw new ArgumentException($"Unsupported sign method: {signMethodType}");
            }

            var body = JsonConvert.SerializeObject(bodyObject);
            var newSign = GenerateSign(body, parameters, appSecret, signMethodHandle);
            return newSign;
        }
    }
}

F#示例#


open System
open System.Collections.Generic
open System.Security.Cryptography
open System.Text
open Newtonsoft.Json

type SignUtils() =
    let mutable support_sign_method = "md5,hmac_sha256"

    let get_md5_sign (param_str: string) (secret: string) =
        let data = param_str + secret
        use md5 = MD5.Create()
        md5.ComputeHash(Encoding.UTF8.GetBytes(data)) |> Array.map (fun b -> b.ToString("x2")) |> String.concat ""

    let get_hmac_sha256_sign (param_str: string) (secret: string) =
        let data = Encoding.UTF8.GetBytes(param_str)
        let key = Encoding.UTF8.GetBytes(secret)
        use sha256 = new HMACSHA256(key)
        sha256.ComputeHash(data) |> Array.map (fun b -> b.ToString("x2")) |> String.concat ""

    let generate_sign (body: string) (parameters: IDictionary<string, string>) (app_secret: string) (sign_method_handle: Func<string, string, string>) =
        let keys = parameters.Keys |> Seq.sort 

        let param_str =
            match body with
            | "" -> ""
            | _ -> "body=" + body + "&"
        parameters
        |> Seq.fold (fun acc k -> acc + k + "=" + parameters.[k] + "&") param_str
        |> fun s -> s + app_secret

        sign_method_handle s app_secret

    member this.Sign (parameters: IDictionary<string, string>) (sign_method_type: string) (app_secret: string) (body_object: obj) =
        let sign_method_handle =
            match sign_method_type with
            | "md5" -> this.get_md5_sign
            | "hmac_sha256" -> this.get_hmac_sha256_sign
            | _ -> failwith "Unsupported sign method: " + sign_method_type

        let body = JsonConvert.SerializeObject(body_object)
        let timestamp = int (DateTime.UtcNow - DateTime(1970, 1, 1)).TotalSeconds
        parameters.[APPID_KEY] <- "your_app_id"
        parameters.[TIMESTAMP_KEY] <- string timestamp
        parameters.[NONCE_KEY] <- "your_nonce"
        parameters.[SIGN_METHOD_KEY] <- sign_method_type
        parameters.[SIGN_TYPE_KEY] <- "MD5"

        this.generate_sign body parameters app_secret sign_method_handle

    member this.GetSupportSignMethod() = support_sign_method
    member this.SetSupportSignMethod(s: string) = support_sign_method <- s

Golang示例#


package signutils

import (
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"sort"
	"strings"
	"time"
)

const (
	appIDKey      = "appid"
	timestampKey  = "timestamp"
	signatureKey  = "sign"
	signMethodKey = "sign_method"
	signTypeKey   = "sign_type"
	nonceKey      = "nonce"
)

type SignUtils struct {
	SupportSignMethod string
}

type SignMethodHandle func(string, string) string

func NewSignUtils() *SignUtils {
	return &SignUtils{
		SupportSignMethod: "md5,hmac_sha256",
	}
}

func (su *SignUtils) GetMd5Sign(paramStr, secret string) string {
	h := md5.New()
	h.Write([]byte(paramStr + secret))
	return hex.EncodeToString(h.Sum(nil))
}

func (su *SignUtils) GetHmacSha256Sign(paramStr, secret string) string {
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(paramStr))
	return hex.EncodeToString(h.Sum(nil))
}

func (su *SignUtils) GenerateSign(body string, parameters map[string]string, appSecret string, signMethodHandle SignMethodHandle) string {
	keys := make([]string, 0, len(parameters))
	for k := range parameters {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	sb := strings.Builder{}
	if len(body) > 0 {
		sb.WriteString(fmt.Sprintf("body=%s&", body))
	}
	for _, k := range keys {
		sb.WriteString(fmt.Sprintf("%s=%s&", k, parameters[k]))
	}
	str := sb.String()
	return signMethodHandle(str, appSecret)
}

func (su *SignUtils) Sign(parameters map[string]string, signMethodType, appSecret string, bodyObject interface{}) string {
	handleMap := map[string]SignMethodHandle{
		"md5":          su.GetMd5Sign,
		"hmac_sha256":  su.GetHmacSha256Sign,
	}
	signMethodHandle, ok := handleMap[signMethodType]
	if !ok {
		panic(fmt.Sprintf("Unsupported sign method: %s", signMethodType))
	}

	bodyBytes, _ := json.Marshal(bodyObject)
	body := string(bodyBytes)
	timestamp := time.Now().Unix()
	parameters[appIDKey] = "your_app_id"
	parameters[timestampKey] = fmt.Sprintf("%d", timestamp)
	parameters[nonceKey] = "your_nonce"
	parameters[signMethodKey] = signMethodType
	parameters[signTypeKey] = "MD5"

	newSign := su.GenerateSign(body, parameters, appSecret, signMethodHandle)
	return newSign
}

PHP示例#

NodeJS示例#

Rust示例#

C++示例#


#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <openssl/md5.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <chrono>
#include <ctime>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

const std::string APPID_KEY = "appid";
const std::string TIMESTAMP_KEY = "timestamp";
const std::string SIGNATURE_KEY = "sign";
const std::string SIGN_METHOD_KEY = "sign_method";
const std::string SIGN_TYPE_KEY = "sign_type";
const std::string NONCE_KEY = "nonce";

class SignUtils {
private:
    std::string support_sign_method = "md5,hmac_sha256";

    std::string get_md5_sign(std::string param_str, std::string secret) {
        unsigned char md[MD5_DIGEST_LENGTH];
        std::string data = param_str + secret;
        MD5(reinterpret_cast<const unsigned char*>(data.c_str()), data.size(), md);
        std::stringstream ss;
        for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
            ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(md[i]);
        }
        return ss.str();
    }

    std::string get_hmac_sha256_sign(std::string param_str, std::string secret) {
        unsigned int result_len;
        unsigned char result[EVP_MAX_MD_SIZE];
        HMAC(EVP_sha256(), reinterpret_cast<const unsigned char*>(secret.c_str()), secret.size(), reinterpret_cast<const unsigned char*>(param_str.c_str()), param_str.size(), result, &result_len);
        std::stringstream ss;
        for (unsigned int i = 0; i < result_len; i++) {
            ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(result[i]);
        }
        return ss.str();
    }

    std::string generate_sign(std::string body, std::map<std::string, std::string> parameters, std::string app_secret, std::function<std::string(std::string, std::string)> sign_method_handle) {
        std::vector<std::string> keys;
        for (const auto& kv : parameters) {
            keys.push_back(kv.first);
        }
        std::sort(keys.begin(), keys.end());

        std::stringstream ss;
        for (const auto& key : keys) {
            ss << key << "=" << parameters[key] << "&";
        }
        ss << app_secret;
        std::string param_str = ss.str();

        return sign_method_handle(param_str, app_secret);
    }

public:
    std::string sign(std::map<std::string, std::string>& parameters, std::string sign_method_type, std::string app_secret, json body_object) {
        std::function<std::string(std::string, std::string)> sign_method_handle;
        if (sign_method_type == "md5") {
            sign_method_handle = [this](std::string param_str, std::string secret) { return this->get_md5_sign(param_str, secret); };
        } else if (sign_method_type == "hmac_sha256") {
            sign_method_handle = [this](std::string param_str, std::string secret) { return this->get_hmac_sha256_sign(param_str, secret); };
        } else {
            throw std::invalid_argument("Unsupported sign method: " + sign_method_type);
        }

        auto body = body_object.dump();
        auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
        parameters[APPID_KEY] = "your_app_id";
        parameters[TIMESTAMP_KEY] = std::to_string(timestamp);
        parameters[NONCE_KEY] = "your_nonce";
        parameters[SIGN_METHOD_KEY] = sign_method_type;
        parameters[SIGN_TYPE_KEY] = "MD5";

        auto new_sign = generate_sign(body, parameters, app_secret, sign_method_handle);
        return new_sign;
    }

    std::string get_support_sign_method() {
        return support_sign_method;
    }

    void set_support_sign_method(std::string support_sign_method) {
        this->support_sign_method = support_sign_method;
    }
};

Lua示例#

Python示例#

Swift示例#

Kotlin示例#

调用示例#

1.
设置参数值
参数名称
appidAppKey
sign_method签名算法, 目前支持的签名算法有两种:MD5(sign_method=md5),HMAC_SHA256(sign_method=hmac-sha256)
timestamp时间戳,默认2分钟内有效
sign签名内容
2.
按ASCII顺序排序
    签名示例:
    签名方式:hmac-sha256
    明文:appid=PltO3gTJ&timestamp=1685590016123
    密钥(appsecret):627ab1bb0c3095e75b4a864edb060db499fa2863
    签名结果(sign):da42d239f9114218d3ac3cd221b9b6376ccdbbe6ef4abb8c07f9236ad9d3c151
    方法:new HmacUtils(HmacAlgorithms.HMAC_SHA_256, 密钥).hmacHex(明文)
    
    签名方式:md5
    明文:appid=PltO3gTJ&sign_method=md5&timestamp=1685597220000
    密钥(appsecret):627ab1bb0c3095e75b4a864edb060db499fa2863
    签名结果(sign):8c9be0645d8afc6406fd32a319a80c0c
    方法: DigestUtils.md5DigestAsHex((明文 + 密钥).getBytes())
注意:签名结果应是小写

期待您的宝贵建议

微信扫描二维码,为我们的AIoT产品提出您的宝贵建议,用户体验是我们坚持不懈的追求。

微信扫描二维码
修改于 2024-04-19 07:50:07
上一页
快速开始
下一页
错误码
Built with