About The Sign

  • Currently, the secret (secrete) is obtained through offline methods or the merchant management platform.

  • secrete:The secret is used to digest and sign the input parameters for API requests. It should be kept by the merchant themselves, and it is essential to ensure strict security measures to prevent its disclosure to external parties.

  • To generate a signature string:all the parameters that need to be verified should be assembled into an array and sorted in ascending order based on the parameter names’ dictionary order using ASCII code. It’s important to note that only the parameter keys are sorted, and the values are not involved in the sorting process.

  • All required field values participate in the signature calculation (excluding “sign”).

Sign Example

  • Parameters Example

JSON

{
  "email": "123213@ach.com",
  "appId": "qmamnbodyqzbdr0w"
}
  • To prepare the string for signing, convert the format of each parameter to “parameter_name=parameter_value” and join them using the “&” symbol. Finally, append the key (secrete) at the end. The resulting string would be as follows:

Text

appId=qmamnbodyqzbdr0w&email=123213@ach.com&key=6fdbaac29eb94bc6b36547ad705e9298
  • Next, apply the SHA-512 algorithm to the prepared signing string to generate the final signature. The signature result is as follows:

Text

8979EEB59CF15246A04E033962CA4084973A9D0F2F5CC08F07B99E9D0338F4486ED7700CF78F6365C2E399ED593B3EF9059F2EC808B5107CED8CC17BA0475962

Java Signature Generation Code Example:

Java

    package io.alchemytech.virtualcard.center.utils;
    import io.alchemytech.basics.shared.common.utils.SHA512Utils;
    import java.util.SortedMap;
    import java.util.TreeMap;

    public class SignUtils {
        /**
         * @param appId Merchant ID
         * @param email      email
         * @param secrete    Secret Key
         * @return
         */
        public static String getSign(String appId, String email, String secrete) {
            SortedMap<Object, Object> map = new TreeMap<>();
            if (email != null && !email.equals("")) {
                map.put("email", email);
            }
            map.put("appId", appId);
            String sign = SHA512Utils.SHAEncrypt(map, secrete);
            return sign;
        }

        public static void main(String[] args) {
            System.out.println(getSign("qmamnbodyqzbdr0w","123@qq.com","6fdbaac29eb94bc6b36547ad705e9298"));
        }
    }

Encryption Utility Class:

Java

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    import java.util.SortedMap;
    public class SHA512Utils {
        public static final String ENCODE = "UTF-8";
        private static Logger logger = LoggerFactory.getLogger(SHA512Utils.class);

        /**
         * Sign the message using SHA algorithm
         *
         * @param signParams Signature Parameter
         * @param key        Encryption Key
         * @return
         */
        public static String SHAEncrypt(SortedMap<Object, Object> signParams, String key) {
            String sign = null;
            StringBuffer sb = new StringBuffer();
            Set es = signParams.entrySet();
            Iterator it = es.iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                String k = (String) entry.getKey();
                String v = (String) entry.getValue();
                if (null != v && !"".equals(v) && !v.equals("null") && !"sign".equals(k) && !"key".equals(k)) {
                    sb.append(k + "=" + v + "&");
                }
            }
            sb.append("key=" + key);
            logger.info("signStr: {}", sb);
            sign = encrypt(sb.toString(), ENCODE).toUpperCase();
            logger.info("sign: {}", sign);
            return sign;
        }

        public static String encrypt(String aValue, String encoding) {
            aValue = aValue.trim();
            byte value[];
            try {
                value = aValue.getBytes(encoding);
            } catch (UnsupportedEncodingException e) {
                value = aValue.getBytes();
            }
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA-512");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
            return toHex(md.digest(value));
        }

        public static String toHex(byte input[]) {
            if (input == null) return null;
            StringBuffer output = new StringBuffer(input.length * 2);
            for (int i = 0; i < input.length; i++) {
                int current = input[i] & 0xff;
                if (current < 16) output.append("0");
                output.append(Integer.toString(current, 16));
            }
            return output.toString();
        }

        /**
         * Verify Signature
         *
         * @param signParams Signature Parameter
         * @param key        Encryption Key
         * @return
         */
        public static boolean verifySHA(SortedMap<Object, Object> signParams, String key) {
            String verifySign = (String) signParams.get("sign");
            String sign = SHAEncrypt(signParams, key);
            if (sign.equalsIgnoreCase(verifySign)) {
                return true;
            }
            return false;
        }
    }

Last updated