签名规则如图所示:
规则参考链接:http://gw.api.alibaba.com/dev/doc/intl/sys_signature.htm?ns=aliexpress.open
下面是自己代码的实现、以及测试:
package com.aliexpress.until;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.http.message.BasicNameValuePair;
public class GrantTool {
private static final String APP_KEY = "10000";
private static final String APP_SECRET = "abcd";
private static final String HMAC_SHA1 = "HmacSHA1";
private static final String UTF8 = "UTF-8";
public static void main(String[] args) throws Exception {
List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
params.add(new BasicNameValuePair("client_id", APP_KEY));
params.add(new BasicNameValuePair("site", "aliexpress"));
params.add(new BasicNameValuePair("redirect_uri", "http://localhost:8888"));
params.add(new BasicNameValuePair("state", "test"));
String signature = new GrantTool().getSignature(params);
System.out.println(signature);
}
/**
* 获取参数签名
* @param pairs 参数键值对
* @return 参数签名的值
* @throws Exception
*/
public String getSignature(List<BasicNameValuePair> params) throws Exception{
if (params == null || params.isEmpty()) {
return null;
}
// 1. 拼接参数key、value
List<String> paramList = new ArrayList<String>();
for (BasicNameValuePair each : params) {
if (each.getValue() != null) {
paramList.add(each.getName()+each.getValue());
}else {
paramList.add(each.getName());
}
}
// 2. 对参数按首字顺序排序
Collections.sort(paramList);
// 3. 拼接,获取最终签名因子
StringBuffer sb = new StringBuffer();
for (String each : paramList) {
sb.append(each);
}
// 4. hmac_sha1签名算法
byte [] bytes = hamc_sha1(sb.toString(), APP_SECRET);
// 5. 将签名转为16进制字符串
String str = hex(bytes);
// 6. 将16进制签名转为大写字符
String signature = str.toUpperCase();
// 返回最终签名数据
return signature;
}
/**
* hmac_sha1签名算法
* @param data 需签名的字符串
* @param encrypKey 签名密钥
* @return 生成的签名
* @throws Exception
*/
private static byte[] hamc_sha1(String data,String encrypKey) throws Exception{
byte [] keyBytes = encrypKey.getBytes(UTF8);
SecretKey secretKey = new SecretKeySpec(keyBytes, HMAC_SHA1);
Mac mac = Mac.getInstance(HMAC_SHA1);
mac.init(secretKey);
byte [] dataBytes = data.getBytes(UTF8);
return mac.doFinal(dataBytes);
}
/**
* byte数组转16进制
* @param bytes 需转换的数组
* @return 16进制数
*/
public static String hex( byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex);
}
return sb.toString();
}
}
测试结果与规则上的预期结果完全一致