在java接口请求调用中,为了保证接口安全,常用的方法是对请求参数进行签名,签名算法一般:
1,请求参数中参入appId和token来进行认证,其中token生成由appId,appKey,请求时间,请求内容生成;
2,将appId,appkey, 请求参数内容,请求时间戳组成键值对
3,将键值对进行字符升序排序,可以使用TreeMap实现
4,参数名和参数值之间用=链接,参数之间用&连接,得到字符A
5,对字符串A进行SHA256算法hash,即生成token值
6,然后对参数值进行urlencode编码
7,参数名和参数之间用=连接,参数和参数之间用&连接,得到字符串B
8,把字符串B,追加到请求url后,进行请求
具体加密代码
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
/**
* @author yw
* @title: SignUtil
* @description:
* @date 2024/10/10
**/
public class SignUtil {
public final static String SHA256 = "SHA-256";
public static void main(String[] args) {
TreeMap<String, String> treeMap = new TreeMap<>();
long time = System.currentTimeMillis();
System.out.println("The time:" + time);
treeMap.put("appId", "15829");
treeMap.put("appKey", "1q2wadl");
treeMap.put("time",time+"");
String query = buildQuery(treeMap);
System.out.println("query:" + query);
String token = sha256AsString(query);
System.out.println("token:" + token);
}
public static String buildQuery(Map<String, String> params) {
StringBuilder queryBuilder = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
// 对参数名和参数值进行编码
String encodedParam = urlEncode(entry.getKey());
String encodedValue = urlEncode(entry.getValue());
// 添加到查询字符串中
if (queryBuilder.length() > 0) {
queryBuilder.append("&");
}
queryBuilder.append(encodedParam)
.append("=")
.append(encodedValue);
}
return queryBuilder.toString();
}
private static String urlEncode(String params) {
try {
return URLEncoder.encode(params, "UTF-8");
} catch (UnsupportedEncodingException e) {
return params;
}
}
public static String sha256AsString(String s) {
return getSafeString(SHA256, s);
}
public static String getSafeString(String algorithm, String s) {
try {
return getAsString(algorithm, s.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
return "";
}
}
/**
* 获取指定文本内容对应的MD5码
* @param plain 文本内容
* @return 文本内容对应的MD5码
* @throws Exception 异常定义
*/
public static String getAsString(String algorithm, byte[] plain) throws Exception {
MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.update(plain);
byte[] buffer = digest.digest();
return toHexByteArray(buffer, 0, buffer.length);
}
/**
* 将数组转换成十六进制字符串
* @param b 数组
* @param m 起始位置
* @param n 个数
* @return 转化后的十六进制字符串
*/
private static String toHexByteArray(byte[] b, int m, int n) {
String md5 = "";
int k = m + n;
if (k > b.length) {
k = b.length;
}
for (int i = m; i < k; i++) {
md5 += Integer.toHexString((b[i] & 0x000000FF) | 0xFFFFFF00).substring(6);
}
return md5.toLowerCase(Locale.getDefault());
}
}