关于签名
说明
- 目前采取线下方式或商户管理平台获取到secrete;
- secrete:是用于对 API 请求的输入参数进行摘要和签名的,商户自行保管且需严格保证此秘钥的安全性,不可对外泄露;
- 生成签名串:将所有需要验签的参数,组成一个数组,并按所有参数名的字典序(ASCII码)升序排序,注意只有参数的 key 名进行排序,值不参与排序。
- 所有必填字段值参与签名(不包含sign)。
签名串示例
如参数:
{
"email": "[email protected]",
"appId": "qmamnbodyqzbdr0w"
}
拼接字符串做签名准备,将格式转化为参数名=参数值形式,并用&符链接,最后再追加上key(secrete),结果如下:
appId=qmamnbodyqzbdr0w&[email protected]&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","[email protected]","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;
}
}
Updated 4 months ago