ARMCLOUD Documentation Center
  • 简体中文
  • English
  • 简体中文
  • English
  • Product introduction
  • Product billing
  • Server OpenAPI
    • Usage Guide
    • API Signature v1.0
    • API Reference
    • Error Codes
    • Callback Business Type Codes
    • Instance List
    • Android Instance Property List
    • Changelog
  • Android SDK
    • Example Setup
    • Interface Description
    • Callback Function
    • Error Code
    • Changelog
  • Web H5 SDK
    • Example Setup
    • Interface Description
    • Callback Function
    • Error Code
    • Changelog
  • Windows PC SDK
    • Example Setup
    • Interface Description
    • Callback Function
    • Changelog
  • Edge-Cloud Communication Development
    • AIDL Access Method
    • System Service API (AIIDL)
  • Scenario solutions
    • XP-like LSP Hook framework
    • Dynamic simulation of sensor data
  • ADI Collection Tool
  • FAQ
    • Platform Basics
    • Storage
    • Network Connectivity
    • Application Management
    • Development and Integration
    • Performance Optimization
    • Billing
    • Technical Support
  • Related agreements
    • Cloud Phone SDK Privacy Policy

Overview

::: warning: Version notes This document describes the signature verification scheme for version 1.0. Recommend new projects use the simpler V2.0 version. :::

ArmCloud's server-side OpenAPI V1.0 signature verification is a comprehensive API authentication solution. Each request verifies your signature to ensure the security of your cloud phone instance information. Please take good care of your account's Access Key ID and Secret Access Key information (hereafter referred to as AK/SK).

Explanation of necessary development parameters

Each API request header must include the following parameters for authentication:

Parameter nameUsage and access instructions
x-dateThe timestamp for sending the request uses UTC time, accurate to seconds, e.g., 20240301T093700Z
x-hostInterface access domain name fixed value openapi-hk.armcloud.net
content-typeThe MIME type of the resource is based on the actual interface specified value, such as: application/json
authorizationFor specific generation rules, please refer to the [authorization Authorization Signature] (#authorization) for specific generation rules.
example: HMAC-SHA256 Credential={AK}/{xDate}/armcloud-paas/request, SignedHeaders=content-type; host; x-content-sha256; x-date, Signature={signature}

Authorization Signature

Authorization Signature Information Generation. To facilitate customer access, the official provider provides SDK-JAVA and SDK-PYTHON reference templates, which internally implement signature verification. By calling AuthorizationUtil.authorizationCreate, (AK, SK, request timestamp, static domain name, request message format, request message information, request type) is passed in. It automatically calculates and generates the authorization signature for requests.

[Reference for obtaining accounts (AK/SK)] (#get-the-account--ak-sk)

[Description of the AuthorizationUtil Signature Generation Class] (#instructions-for-the-authorizationutil-signature-generation-class)

[SDK-JAVA Reference Template] (#sdk-java-reference-template)

[SDK-PYTHON Reference Template] (#sdk-python-reference-template)

Obtaining Account (AK/SK)

Before starting to generate authorization signatures, you need to obtain the Access Key ID and Secret Access Key for API request authentication.
Steps: After logging in to the ARMCloud platform, User Management -> Account Information In the menu, appKey is AK, appSecret is SK.

AuthorizationUtil Signature Generation Class Description

Analysis of the SDK-JAVA Authorization.authorizationCreate signature generation method.
Class name: AuthorizationUtil
Authorization signature generation method: AuthorizationUtil.authorizationCreate(String AK, String SK, String xDate, String xHost, String contentTypeJson, Map<String,Object> requestBody, String httpMethodStr)

Parameter nameTypeExample valuesParameter description
AKStringxxxxThe Access Key ID of the account
SKStringxxxxSecret Access Key for the account
xDateString20240301T093700ZThe requested timestamp uses UTC time, accurate to the second
xHostStringopenapi-hk.armcloud.netStatic domain name
contentTypeJsonStringapplication/jsonRequest message format
requestBodyMap<String,Object>new Map<String,Object>Request message information
httpMethodStrStringPOSTRequest method: GET or POST
/**
 * Signature tool class
*/
public static class AuthorizationUtil {
    private static final String service = "armcloud-paas";               //Fixed service name
    private static final String algorithm = "HMAC-SHA256";               //Fixed signature algorithm

    /**
     * authorization generation tool method
     *
     * @param Access Key ID for the AK account
     * @param Secret Access Key for SK accounts
     * @param xDate follows the ISO 8601 standard time format: YYYYMMDD'T'HHMMSS'Z' for example: 20201103T104027Z
     * @param xHost fixed domain
     * @param contentTypeJson requests content formatting
     * @param requestBody Requests JSON data
     * @param httpMethodStr Request method: GET or POST
     * @return authorization
     * @throws Exception
     */
    public static String authorizationCreate(String AK, String SK, String xDate, String xHost, String contentTypeJson
            , Map<String,Object> requestBody, String httpMethodStr) throws Exception {
        byte[] body = new byte[0];
        if (requestBody != null) {
            if ("GET".equals(httpMethodStr)) {
                StringBuilder sb = new StringBuilder();
                Iterator<String> keys = requestBody.keySet().iterator();
                while (keys.hasNext()) {
                    String key = keys.next();
                    sb.append(key).append("=").append(requestBody.get(key)).append("&");
                }
                // Remove the last '&' character (if present)
                if (sb.length() > 0) {
                    sb.setLength(sb.length() - 1);
                }
                body = sb.toString().getBytes(StandardCharsets.UTF_8);
                
            } else {
                body = MapToJsonUtil.mapToJson(requestBody).getBytes(StandardCharsets.UTF_8);
            }
        }

        final String xContentSha256 = hashSHA256(body);
        //Short-term format
        final String shortDate = xDate.substring(0, 8);
        String signedHeaders = "content-type;host;x-content-sha256;x-date";
        String canonicalStringBuilder =
                "host:" + xHost + "\n" + "x-date:" + xDate + "\n" + "content-type:" + contentTypeJson + "\n" 
                        + "signedHeaders:" + signedHeaders + "\n" + "x-content-sha256:" + xContentSha256;
        String hashCanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
        String credentialScope = shortDate + "/" + service + "/request";
        String signString = algorithm + "\n" + xDate + "\n" + credentialScope + "\n" + hashCanonicalString;
        byte[] signKey = genSigningSecretKeyV4(SK, shortDate, service);
        String signature = bytesToHex(hmacSHA256(signKey, signString));
        //authorization
        String authorization = "HMAC-SHA256 Credential=" + AK + "/" + xDate + "/" + service 
                + "/request, SignedHeaders=" + signedHeaders + ", Signature=" + signature;
        return authorization;
    }

    private static byte[] genSigningSecretKeyV4(String secretKey, String shortXDate, String service) throws Exception {
        byte[] kDate = hmacSHA256((secretKey).getBytes(), shortXDate);
        byte[] kService = hmacSHA256(kDate, service);
        return hmacSHA256(kService, "request");
    }

    private static String hashSHA256(byte[] content) throws Exception {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            return bytesToHex(md.digest(content));
        } catch (Exception e) {
            throw new Exception("Unable to compute hash while signing request: " + e.getMessage(), e);
        }
    }

    private static String bytesToHex(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return "";
        }
        final StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    private static byte[] hmacSHA256(byte[] key, String content) throws Exception {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(key, "HmacSHA256"));
            return mac.doFinal(content.getBytes());
        } catch (Exception e) {
            throw new Exception("Unable to calculate a request signature: " + e.getMessage(), e);
        }
    }
}

SDK-JAVA reference template

[Download SDK-JAVA] (https://oss-hk01.armcloud.net/arm-cloud-sdk/sdk_java.zip)

package net.armcloud.console.sdk.test;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * Signature testing class
 */
public class AuthorizationTest {
    //GET Signature Request Test—POST Signature Request Test
    public static void main(String[] args) throws Exception {
        //Replace it with AK from your own account
        final String AK = "xxxxxx";
        //SK replaced with his own account
        final String SK = "xxxx";
        //Static domain name
        final String xHost = "openapi-hk.armcloud.net";
        //Request message format
        final String contentType = "application/json";

        //Query the supported callback type interface
        selectList( AK, SK, xHost, contentType);
        //Instance grouped list interface
        groupInfos( AK, SK, xHost, contentType);

    }

    /**
     * Query the supported callback type interface
     * @param AK
     * @param SK
     * @param xHost
     * @param contentType
     * @throws Exception
     */
    private static void selectList ( String AK, String SK, String xHost, String contentType) throws Exception {
        String postUrlAddress = "https://"+xHost+"/openapi/open/config/selectList";
        Map<String,Object> getRequestBody = new HashMap<>();
        get(postUrlAddress, AK, SK, xHost, contentType, getRequestBody);
    }

    /**
     * Instance grouped list interface
     * @param AK
     * @param SK
     * @param xHost
     * @param contentType
     * @throws Exception
     */
    private static void groupInfos ( String AK, String SK, String xHost, String contentType) throws Exception {
        String postUrlAddress = "https://"+xHost+"/openapi/open/group/infos";
        List<Integer> jsonArray = new ArrayList<>();
        jsonArray.add(1);
        Map<String,Object> postRequestBody = new HashMap<>();
        postRequestBody.put("padCode", "AC32010180376");
        postRequestBody.put("groupIds", jsonArray);
        post(postUrlAddress, AK, SK, xHost, contentType, postRequestBody);
    }



    /**
     * GET encapsulation request method
     *
     * @param urlAddress request address
     * @param AK            AK
     * @param SK            SK
     * @param xHost fixed domain
     * @param contentType Request packet format
     * @param requestBody Requests packets
     * @throws Exception
     */
    public static String get(String urlAddress, String AK, String SK, String xHost, String contentType
            , Map<String,Object> requestBody) throws Exception {
        LocalDateTime localDateTime = LocalDateTime.now();                                   // At the current time
        String xDate = localDateTimeToStringUTC(localDateTime);                              // UTC time format
        URL url = new URL(urlAddress + getParamString(requestBody));                    // Create a URL object
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();             // Open the connection
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5000);                                                  // Set the connection timeout to 5 seconds
        connection.setReadTimeout(5000);                                                     // Set the read timeout to 5 seconds
        connection.setRequestProperty("content-type", contentType);                          // Set the request header
        connection.setRequestProperty("x-host", xHost);
        connection.setRequestProperty("x-date", xDate);
        //SDK AuthorizationUtil: The authorizationCreate tool class uses the authorizationCreate method to obtain the authorization authentication interface
        String authorization = AuthorizationUtil.authorizationCreate(AK, SK, xDate, xHost, contentType
                , requestBody, "GET");
        connection.setRequestProperty("authorization", authorization);
        try {
            InputStream in = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            System.out.println("GET Response Body: " + response);
            return String.valueOf(response);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            connection.disconnect();
        }
        return null;
    }



    /**
     * Post encapsulation request method
     *
     * @param urlAddress request address
     * @param AK            AK
     * @param SK            SK
     * @param xHost fixed domain
     * @param contentType Request packet format
     * @param requestBody Requests packets
     * @throws Exception
     */
    public static String post(String urlAddress, String AK, String SK, String xHost, String contentType
            , Map<String,Object> requestBody) throws Exception {
        LocalDateTime localDateTime = LocalDateTime.now();                                  //At the current time
        String xDate = localDateTimeToStringUTC(localDateTime);                             //UTC time format
        URL url = new URL(urlAddress);                                                      // Create a URL object
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();            // Open the connection
        connection.setRequestMethod("POST");
        connection.setConnectTimeout(5000);                                                 // Set the connection timeout to 5 seconds
        connection.setReadTimeout(5000);                                                    // Set the read timeout to 5 seconds
        connection.setRequestProperty("content-type", contentType);                         // Set the request header
        connection.setRequestProperty("x-host", xHost);
        connection.setRequestProperty("x-date", xDate);
        connection.setDoOutput(true);                                                       // Allows writing to request bodies
        String authorization = AuthorizationUtil.authorizationCreate(AK, SK, xDate, xHost, contentType
                , requestBody, "POST");
        connection.setRequestProperty("authorization", authorization);
        // Convert JSON data into byte arrays
        byte[] outputInBytes = MapToJsonUtil.mapToJson(requestBody).getBytes(StandardCharsets.UTF_8);
        try {
            // Obtain the output stream and write the data
            OutputStream os = connection.getOutputStream();
            os.write(outputInBytes);
            Scanner scanner = new Scanner(connection.getInputStream(), StandardCharsets.UTF_8.name());
            StringBuilder response = new StringBuilder();
            while (scanner.hasNext()) {
                response.append(scanner.next());
            }
            System.out.println("POST Response Body: " + response);
            return String.valueOf(response);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            connection.disconnect();
        }
        return null;
    }

    /**
     * Time zone switching
     *
     * @param localDateTime
     * @return
     */
    public static String localDateTimeToStringUTC(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
        ZonedDateTime utcDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC"));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");

        return utcDateTime.format(formatter);
    }

    /**
     * get request parameter simple parsing and concatenation
     *
     * @param map
     * @return
     */
    public static String getParamString(Map<String, Object> map) {
        StringBuilder sb = new StringBuilder();
        if (map != null) {
            sb.append("?");

            Iterator<String> keys = map.keySet().iterator();
            while (keys.hasNext()) {
                String key = keys.next();
                sb.append(key).append("=").append(map.get(key)).append("&");
            }
            // Remove the last '&' character (if present)
            if (sb.length() > 0) {
                sb.setLength(sb.length() - 1);
            }
        }
        return sb.toString();
    }


    /**
     * map to JsonUtil utility class
     */
    public static class MapToJsonUtil {

        public static String mapToJson(Map<String, Object> map) {
            StringBuilder jsonString = new StringBuilder();

            jsonString.append("{");

            Set<Map.Entry<String, Object>> entrySet = map.entrySet();
            boolean firstEntry = true;

            for (Map.Entry<String, Object> entry : entrySet) {
                if (!firstEntry) {
                    jsonString.append(",");
                }
                firstEntry = false;

                jsonString.append("\"");
                jsonString.append(entry.getKey());
                jsonString.append("\":");

                Object value = entry.getValue();
                if (value instanceof String) {
                    jsonString.append("\"");
                    jsonString.append(value);
                    jsonString.append("\"");
                } else if (value instanceof Number || value instanceof Boolean) {
                    jsonString.append(value);
                } else if (value instanceof Map) {
                    jsonString.append(mapToJson((Map<String, Object>) value));
                } else if (value instanceof Iterable<?>) {
                    jsonString.append(iterableToJson((Iterable<?>) value));
                } else if (value == null) {
                    jsonString.append("null");
                } else {
                    // Handle other types if necessary
                    jsonString.append("\"");
                    jsonString.append(value.toString());
                    jsonString.append("\"");
                }
            }

            jsonString.append("}");
            return jsonString.toString();
        }

        private static String iterableToJson(Iterable<?> iterable) {
            StringBuilder jsonArray = new StringBuilder();
            jsonArray.append("[");

            boolean firstElement = true;
            for (Object element : iterable) {
                if (!firstElement) {
                    jsonArray.append(",");
                }
                firstElement = false;

                if (element instanceof String) {
                    jsonArray.append("\"");
                    jsonArray.append(element);
                    jsonArray.append("\"");
                } else if (element instanceof Number || element instanceof Boolean) {
                    jsonArray.append(element);
                } else if (element instanceof Map) {
                    jsonArray.append(mapToJson((Map<String, Object>) element));
                } else if (element instanceof Iterable<?>) {
                    jsonArray.append(iterableToJson((Iterable<?>) element));
                } else if (element == null) {
                    jsonArray.append("null");
                } else {
                    // Handle other types if necessary
                    jsonArray.append("\"");
                    jsonArray.append(element.toString());
                    jsonArray.append("\"");
                }
            }

            jsonArray.append("]");
            return jsonArray.toString();
        }


    }



    /**
     * Signature tool class
     */
    public static class AuthorizationUtil {
        private static final String service = "armcloud-paas";               //Fixed service name
        private static final String algorithm = "HMAC-SHA256";               //Fixed signature algorithm

        /**
         * authorization generation tool method
         *
         * @param Access Key ID for the AK account
         * @param Secret Access Key for SK accounts
         * @param xDate follows the ISO 8601 standard time format: YYYYMMDD'T'HHMMSS'Z' for example: 20201103T104027Z
         * @param xHost fixed domain
         * @param contentTypeJson requests content formatting
         * @param requestBody Requests JSON data
         * @param httpMethodStr Request method: GET or POST
         * @return authorization
         * @throws Exception
         */
        public static String authorizationCreate(String AK, String SK, String xDate, String xHost
                , String contentTypeJson, Map<String,Object> requestBody, String httpMethodStr) throws Exception {
            byte[] body = new byte[0];
            if (requestBody != null) {
                if ("GET".equals(httpMethodStr)) {
                    StringBuilder sb = new StringBuilder();
                    Iterator<String> keys = requestBody.keySet().iterator();
                    while (keys.hasNext()) {
                        String key = keys.next();
                        sb.append(key).append("=").append(requestBody.get(key)).append("&");
                    }
                    // Remove the last '&' character (if present)
                    if (sb.length() > 0) {
                        sb.setLength(sb.length() - 1);
                    }
                    body = sb.toString().getBytes(StandardCharsets.UTF_8);
                } else {
                    body = MapToJsonUtil.mapToJson(requestBody).getBytes(StandardCharsets.UTF_8);
                }
            }

            final String xContentSha256 = hashSHA256(body);
            //Short-term format
            final String shortDate = xDate.substring(0, 8);
            String signedHeaders = "content-type;host;x-content-sha256;x-date";
            String canonicalStringBuilder =
                    "host:" + xHost + "\n" + "x-date:" + xDate + "\n" + "content-type:" + contentTypeJson + "\n" 
                            + "signedHeaders:" + signedHeaders + "\n" + "x-content-sha256:" + xContentSha256;
            String hashCanonicalString = hashSHA256(canonicalStringBuilder.getBytes());
            String credentialScope = shortDate + "/" + service + "/request";
            String signString = algorithm + "\n" + xDate + "\n" + credentialScope + "\n" + hashCanonicalString;
            byte[] signKey = genSigningSecretKeyV4(SK, shortDate, service);
            String signature = bytesToHex(hmacSHA256(signKey, signString));
            //authorization
            String authorization = "HMAC-SHA256 Credential=" + AK + "/" + xDate + "/" + service 
                    + "/request, SignedHeaders=" + signedHeaders + ", Signature=" + signature;
            return authorization;
        }

        private static byte[] genSigningSecretKeyV4(String secretKey, String shortXDate
                , String service) throws Exception {
            byte[] kDate = hmacSHA256((secretKey).getBytes(), shortXDate);
            byte[] kService = hmacSHA256(kDate, service);
            return hmacSHA256(kService, "request");
        }

        private static String hashSHA256(byte[] content) throws Exception {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                return bytesToHex(md.digest(content));
            } catch (Exception e) {
                throw new Exception("Unable to compute hash while signing request: " + e.getMessage(), e);
            }
        }

        private static String bytesToHex(byte[] bytes) {
            if (bytes == null || bytes.length == 0) {
                return "";
            }
            final StringBuilder result = new StringBuilder();
            for (byte b : bytes) {
                result.append(String.format("%02x", b));
            }
            return result.toString();
        }

        private static byte[] hmacSHA256(byte[] key, String content) throws Exception {
            try {
                Mac mac = Mac.getInstance("HmacSHA256");
                mac.init(new SecretKeySpec(key, "HmacSHA256"));
                return mac.doFinal(content.getBytes());
            } catch (Exception e) {
                throw new Exception("Unable to calculate a request signature: " + e.getMessage(), e);
            }
        }
    }
}

SDK-PYTHON reference template

[Download SDK-PYTHON] (https://oss-hk01.armcloud.net/arm-cloud-sdk/sdk_python.zip)

import hmac
import hashlib
import json
from typing import Dict, Optional

# Define the constant
SERVICE = "armcloud-paas"
ALGORITHM = "HMAC-SHA256"
X_HOST = "openapi-hk.armcloud.net"
CONTENT_TYPE_JSON = "application/json"

def authorization_create(ak: str, sk: str, request_body: Optional[Dict], x_date: str, http_method: str) -> str:
    """
    Generates the Authorization request header
    :param ak: Access Key
    :param sk: Secret Key
    :param request_body: request form (dictionary form)
    :param x_date: Timestamp
    :param http_method: HTTP Method (GET/POST)
    :return: Authorization request header
    """
    body = b""
    if request_body is not None:
        if http_method.upper() == "GET":
            # When GET requests, concatenate the parameters as key1=value1&key2=value2
            body = "&".join(f"{key}={value}" for key, value in request_body.items()).encode("utf-8")
        else:
            # When POSTing a request, the request body is converted into a JSON string
            body = map_to_json(request_body).encode("utf-8")

    x_content_sha256 = hash_sha256(body)
    short_date = x_date[:8]
    signed_headers = "content-type;host;x-content-sha256;x-date"
    canonical_string = (
        f"host:{X_HOST}\n"
        f"x-date:{x_date}\n"
        f"content-type:{CONTENT_TYPE_JSON}\n"
        f"signedHeaders:{signed_headers}\n"
        f"x-content-sha256:{x_content_sha256}"
    )
    hash_canonical_string = hash_sha256(canonical_string.encode("utf-8"))
    credential_scope = f"{short_date}/{SERVICE}/request"
    sign_string = f"{ALGORITHM}\n{x_date}\n{credential_scope}\n{hash_canonical_string}"
    sign_key = gen_signing_secret_key_v4(sk, short_date, SERVICE)
    signature = bytes_to_hex(hmac_sha256(sign_key, sign_string.encode("utf-8")))
    authorization = (
        f"{ALGORITHM} Credential={ak}/{x_date}/{SERVICE}/request, "
        f"SignedHeaders={signed_headers}, Signature={signature}"
    )
    return authorization

def gen_signing_secret_key_v4(secret_key: str, short_x_date: str, service: str) -> bytes:
    """
    Generate the signature key
    :param secret_key: Key
    :param short_x_date: Short Date (yyyyMMdd)
    :param service: Service name
    :return: Byte data of the signature key
    """
    k_date = hmac_sha256(secret_key.encode("utf-8"), short_x_date.encode("utf-8"))
    k_service = hmac_sha256(k_date, service.encode("utf-8"))
    return hmac_sha256(k_service, b"request")

def hash_sha256(content: bytes) -> str:
    """
    Calculate the SHA-256 hash value
    :param content: Input content (byte data)
    :return: The hexadecimal string of the hash value
    """
    sha256 = hashlib.sha256()
    sha256.update(content)
    return sha256.hexdigest()

def bytes_to_hex(bytes_data: bytes) -> str:
    """
    Convert byte data into hexadecimal strings
    :param bytes_data: Byte data
    :return: Hexadecimal string
    """
    if not bytes_data:
        return ""
    return "".join(f"{byte:02x}" for byte in bytes_data)

def hmac_sha256(key: bytes, content: bytes) -> bytes:
    """
    Calculate HMAC-SHA256
    :param key: Key (byte data)
    :param content: Input content (byte data)
    :return: Byte data of HMAC results
    """
    return hmac.new(key, content, hashlib.sha256).digest()

def map_to_json(map_obj):
    json_string = "{"
    first_entry = True

    for key, value in map_obj.items():
        if not first_entry:
            json_string += ","
        first_entry = False

        json_string += f'"{key}":'

        if isinstance(value, str):
            json_string += f'"{value}"'
        elif isinstance(value, (int, float, bool)):
            json_string += str(value).lower() if isinstance(value, bool) else str(value)
        elif isinstance(value, dict):
            json_string += map_to_json(value)
        elif isinstance(value, (list, tuple)):
            json_string += iterable_to_json(value)
        elif value is None:
            json_string += "null"
        else:
            json_string += f'"{str(value)}"'

    json_string += "}"
    return json_string

def iterable_to_json(iterable):
    json_string = "["
    first_item = True

    for item in iterable:
        if not first_item:
            json_string += ","
        first_item = False

        if isinstance(item, str):
            json_string += f'"{item}"'
        elif isinstance(item, (int, float, bool)):
            json_string += str(item).lower() if isinstance(item, bool) else str(item)
        elif isinstance(item, dict):
            json_string += map_to_json(item)
        elif isinstance(item, (list, tuple)):
            json_string += iterable_to_json(item)
        elif item is None:
            json_string += "null"
        else:
            json_string += f'"{str(item)}"'

    json_string += "]"
    return json_string

# Example usage
if __name__ == "__main__":
    ak = "ak"
    sk = "sk"
    request_body = {}  # Request body
    x_date = "20250126T230940Z"  # Timestamp
    http_method = "GET"  # HTTP method

    authorization = authorization_create(ak, sk, request_body, x_date, http_method)
    print("Authorization Header:", authorization)
Prev
Usage Guide
Next
API Reference