通用API接口签名算法(参考淘宝)

java接口签名算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Map;

public class SignUtil {


public static final String SIGN_METHOD_MD5 = "md5";
public static final String SIGN_METHOD_HMAC = "hmac";
private static final String CHARSET_UTF8 = "utf-8";


/**
* 对TOP请求进行签名。
*/
public static String signTopRequest(Map<String, String> params, String secret, String signMethod) throws IOException {
// 第一步:检查参数是否已经排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);

// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
if (SIGN_METHOD_MD5.equals(signMethod)) {
query.append(secret);
}
for (String key : keys) {
String value = params.get(key);
if (isNotEmpty(key) && isNotEmpty(value)) {
query.append(key).append(value);
}
}

// 第三步:使用MD5/HMAC加密
byte[] bytes;
if (SIGN_METHOD_HMAC.equals(signMethod)) {
bytes = encryptHMAC(query.toString(), secret);
} else {
query.append(secret);
bytes = encryptMD5(query.toString());
}

// 第四步:把二进制转化为大写的十六进制
return byte2hex(bytes);
}

/**
* 对字节流进行HMAC_MD5摘要。
*/
private static byte[] encryptHMAC(String data, String secret) throws IOException {
byte[] bytes = null;
try {
SecretKey secretKey = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), "HmacMD5");
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
mac.init(secretKey);
bytes = mac.doFinal(data.getBytes(CHARSET_UTF8));
} catch (GeneralSecurityException gse) {
throw new IOException(gse.toString());
}
return bytes;
}

/**
* 对字符串采用UTF-8编码后,用MD5进行摘要。
*/
private static byte[] encryptMD5(String data) throws IOException {
return encryptMD5(data.getBytes(CHARSET_UTF8));
}

/**
* 对字节流进行MD5摘要。
*/
private static byte[] encryptMD5(byte[] data) throws IOException {
byte[] bytes = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
bytes = md.digest(data);
} catch (GeneralSecurityException gse) {
throw new IOException(gse.toString());
}
return bytes;
}

/**
* 把字节流转换为十六进制表示方式。
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}

private static boolean isNotEmpty(String value) {
int strLen;
if (value == null || (strLen = value.length()) == 0) {
return false;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(value.charAt(i)) == false)) {
return true;
}
}
return false;
}
public static void main(String[] args) throws Exception {
Map<String, String> params = new HashMap<String, String>();
// 公共参数
params.put("method", "taobao.item.seller.get");
params.put("app_key", appKey);
params.put("session", sessionKey);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
params.put("timestamp", df.format(new Date()));
params.put("format", "json");
params.put("v", "2.0");
params.put("sign_method", "hmac");
// 业务参数
params.put("fields", "num_iid,title,nick,price,num");
params.put("num_iid", "123456789");
// 签名参数
params.put("sign", signTopRequest(params, appSecret, SIGN_METHOD_HMAC));
}
}

参考淘宝api文档:https://open.taobao.com/doc.htm?docId=130&docType=1

JavaScript接口签名算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//1、 helper_tbsign 文件 
var md5 = require("blueimp-md5").md5;
// 淘宝网的App信息
var config = {
AppKey: '123456',
AppSecret: '123456'
};

var tbSign = function (obj) {
// 时间戳
var time = new Date();
var timestamp = time.getFullYear() + "-" +
("0" + (time.getMonth() + 1)).slice(-2) + "-" +
("0" + time.getDate()).slice(-2) + ' ' +
("0" + time.getHours()).slice(-2) + ":" +
("0" + time.getMinutes()).slice(-2) + ":" +
("0" + time.getSeconds()).slice(-2);
obj.timestamp = timestamp;//此处timestamp根据和java的 timestamp字段保持一致

// 程序key
obj.app_key = config.AppKey;//此处app_key根据和java的 key字段保持一致

// 参数数组
var arr = [];
// 循环添加参数项
for(var p in obj){//此处可以判断字段和对象是否为空白 空 的字符串 和java保持一致
arr.push(p + obj[p]);
}
// 排序
arr.sort();
// 参数喘
var msg = arr.join('');
console.log(msg);

// Hmac 签名
var sign = md5(msg, config.AppSecret);

// 返回
return {
timestamp:timestamp,
sign:sign.toUpperCase()
}
}
module.exports.tbSign = tbSign;


// 2、 使用
var helperTb = require('./helper_tbsign');
// 短信发送的参数对象
var obj = {
format : 'json',
method : 'alibaba.aliqin.fc.sms.num.send',
partner_id : 'top-sdk-java-20151020',
rec_num : '13901234567',
sign_method : 'hmac',
sms_type : 'normal',
sms_param : '{"code":"1234", "product":"Demo"}',
sms_free_sign_name : '注册验证',
sms_template_code : 'SMS_123456',
v : '2.0',
timestamp : '2015-10-20 20:41:05'
}
var sign = helperTb.tbSign(obj);
开发者首页 wechat
欢迎您扫一扫上面的微信公众号