将请求参数按一定规则生成相应的签名,实现生成签名和验证签名
签名规则
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),
使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空,则不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或支付平台主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 支付平台接口可能增加字段,验证签名时必须支持增加的扩展字段。
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
下面展示一些 内联代码片
。
// MD5Utils
public class MD5Utils {
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}
// 生成签名SignUtils
public class SignUtils {
private static String key = "658be2332b731b8dd659f46b4779dfd8";
/**
* 根据规则生成签名方法
*
* @param params 加密字段
* @return 返回签名
*/
public static String getSign(HashMap<String, Object> params) {
//TreeMap 进行排序
Map<String, Object> sortedMap = new TreeMap<String,Object>(params);
//获取键值对
Set<Map.Entry<String, Object>> entrySet = sortedMap.entrySet();
//遍历并且拼接
StringBuilder stringA = new StringBuilder();
for (Map.Entry<String, Object> entry : entrySet) {
String key = entry.getKey();
if (key != null && !key.equals("sign")) {
stringA.append(key).append("=").append(entry.getValue()).append("&");
}
}
stringA.append("key").append("=").append(key);
System.out.println(stringA);
StringBuilder stringSignTemp = stringA;
System.out.println(stringSignTemp);
return MD5Utils.MD5Encode(stringSignTemp.toString(),"UTF-8").toUpperCase();
}
/**
* 验证签名方法
*
* @param params 加密字段
* @param sign 签名
* @return
*/
public static boolean verifySign(HashMap<String, Object> params, String sign) {
String trueSign = getSign(params);
return sign.equals(trueSign);
}
}