关于签名

说明

  • 目前采取线下方式或商户管理平台获取到secrete;
  • secrete:是用于对 API 请求的输入参数进行摘要和签名的,商户自行保管且需严格保证此秘钥的安全性,不可对外泄露;
  • 生成签名串:将所有需要验签的参数,组成一个数组,并按所有参数名的字典序(ASCII码)升序排序,注意只有参数的 key 名进行排序,值不参与排序。
  • 所有必填字段值参与签名(不包含sign)。

签名串示例

如参数:

{ "email": "123213@ach.com", "appId": "qmamnbodyqzbdr0w" }

拼接字符串做签名准备,将格式转化为参数名=参数值形式,并用&符链接,最后再追加上key(secrete),结果如下:

appId=qmamnbodyqzbdr0w&email=123213@ach.com&key=6fdbaac29eb94bc6b36547ad705e9298

接着对待加签字符串 做 SHA-512 算法进行摘要签名,生成最终的签名, 签名结果如下:

 8979EEB59CF15246A04E033962CA4084973A9D0F2F5CC08F07B99E9D0338F4486ED7700CF78F6365C2E399ED593B3EF9059F2EC808B5107CED8CC17BA0475962J

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 商户号 * @param email email * @param secrete 秘钥 * @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")); } }

加密工具类:

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); /** * 对报文进行SHA签名 * * @param signParams 签名参数 * @param 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(); } /** * 验签 * * @param signParams 签名参数 * @param 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; } }

Did this page help you?