Skip to content
Last updated

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):

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)

//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:

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.pngauthor2.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.