# Authorization Guide

## 1. Overview

When developer send requests to Keeta APIs, the request body **must include a signature parameter (field name: sig)**. Keeta uses this signature to verify request legitimacy and security.

Correspondingly, when Keeta pushes messages (e.g., Webhook notifications) to developer applications, it includes a signature parameter. Developer applications **must validate this signature in strict compliance with the signature rules** to ensure message authenticity and integrity, preventing tampering or forgery.

## 2. Signature Calculation

**Step 1: Parameter Sorting & Concatenation**

1. Sort all parameters in ASCII order (lexicographical order)
2. Concatenate as URL key-value pairs: key1=value1&key2=value2...


**Note:** JSON parameter values (e.g., shopCategory) require no internal sorting.

**Step 2: Construct Encryption String**

**Concatenate the conponents in this exact order to form the pre-encryption string:**

URL + String calculated during Step 1 + AppSecret

**Example:**

AppSecret = abc

Pre-encryption String = https://open.mykeeta.com/api/open/product/shopcategory/update?accessToken=abc&appId=123&shopCategory={"id":123,"name":"test","type":0,"description":null}&shopId=123&timestamp=1682566749abc

**Note:** Chinese characters require no encoding

**Step 3: Generate SHA-256 Signature**

Apply SHA-256 encryption to the Step 2 string to get a 64-character signature, e.g. 48eb6d562bb0673e3db753831f032be237fc19d1e5c33fcb5386d89c0eebca86

**Note**: Empty parameters (defined as parameters with no value) must be included for both parameter concatenation and signature calculation.

**Step 4: Add the Signature to Request Parameters**

Assign the generated signature to the sig parameter, include sig as a request parameter, and submit the request.

**Example (POST request):**


```JSON
curl -X POST https://open.mykeeta.com/api/open/product/shopcategory/update
-H 'Content-Type: application/json'
-d '{
    "appId": 123,
    "shopId": 123,
    "accessToken": "abc",
    "shopCategory": {
        "id": 123,
        "name": "test",
        "type": 0,
        "description": null
    },
    "timestamp": "1682566749",
    "sig": "48eb6d562bb0673e3db753831f032be237fc19d1e5c33fcb5386d89c0eebca86"
}'
```

## 3. Code Implementation (Java)


```java
//demo
public static void main(String[] args) {
        String url = "https://open.mykeeta.com/api/open/product/shopcategory/update";
        Map<String, Object> params = new HashMap<>();
        params.put("appId", 123);
        params.put("timestamp", 1682566749);
        params.put("accessToken", "abc");
        params.put("shopId", "123");
        params.put("shopCategory", "{\"id\":123,\"name\":\"test\",\"type\":0,\"description\":null}");
        String sortedParamStr = getSortedParam(params);
        String secret = "abc";
        String sig = getSig(url, sortedParamStr, secret);
        System.out.println("sig:" + sig);
    }

public static String getSortedParam(Map params) {
        Object[] key_arr = params.keySet().toArray();
        Arrays.sort(key_arr);
        String str = "";
        for (Object key : key_arr) {
            if (key.equals("sig")) {
                continue;
            }
            Object val = params.get(key);
            str += "&" + key + "=" + val;
        }
        return str.replaceFirst("&", "");
    }

 public static String getSig(String url, String sortedParamStr, String appSecret) {
        String sigString = digest(url + "?" + sortedParamStr + appSecret);
        log.info("getSig(url:{},sortedParamsStr:{}, secret:***},return sig:{})", url, 
        sortedParamStr, sigString);
        return sigString;
 }

public static String digest(String src) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MessageDigest.getInstance(\"SHA-256\") exception", e);
        }
        return byte2hex(md.digest(src.getBytes(StandardCharsets.UTF_8)));
}

private static String byte2hex(byte[] hash) {
        StringBuilder hexString = new StringBuilder(2 * hash.length);
        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
}
```

## 4.FAQ

### 4.1 Image Upload Signature Calculation

**Supported Image Formats**: JPG / JPEG / PNG / BMP

**Content-Type Requirement**: multipart/form-data

**Signature Exclusion:** The imgData parameter (containing image byte array) **must be excluded from signature calculation**.

**Image-to-Byte Conversion Reference**:


```java
public static byte[] image2byte(String path) throws IOException {
    FileImageInputStream input = null;
    ByteArrayOutputStream output = null;
    try {
        input = new FileImageInputStream(new File(path));
        output = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int numBytesRead;
        while ((numBytesRead = input.read(buf)) != -1) {
            output.write(buf, 0, numBytesRead);
        }
        byte[] bytes = output.toByteArray();
        return bytes;
    } finally {
        if (input != null) {
            input.close();
        }
        if (output != null) {
            output.close();
        }
    }
}
```

**Parameter Location Rules**: imgData parameter must be placed in the request body. Other parameters must be placed in request parameters.

author1.png
author2.png
### 4.2 Is Strict Parameter Order Enforced?

Yes. All signature parameters **must be sorted in ASCII lexicographical order**, including:

- All parameters except sig
- Empty parameters (with no value)


### 4.3 How to Handle JSON Parameters?

- For parameters containing JSON values:
  - No internal sorting of JSON fields
  - Use the original JSON string as-is
  - No additional encoding


### 4.4 Signature Verification Failed - Troubleshooting

Perform step-by-step verification:

- Parameter concatenation order (ASCII sorted)
- Inclusion of empty parameters
- URL/body consistency
- AppSecret correctness


### 4.5 Chinese Character Encoding Requirement

No encoding needed. Use Chinese characters directly in their original form during concatenation.

### 4.6 Signature tools

You can easily calculate the correct signature through this tool, helping you quickly verify whether your code implementation is correct. [>>> Click here](https://keetatool1.mynocode.host/)