api接口加密———java
程序员文章站
2024-01-03 21:17:22
...
package com.lili.api.util;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zhph.api.vo.ApiModel;
外部接口工具类:
public class SignUtils {
private static Logger LOGGER = LoggerFactory.getLogger(SignUtils.class);
private static final String secretKey = "2116b98d7dc71ec2cd3a9f50";
private static final String appKeyId= "375028bd0e680e91be502e86";
public static void main(String[] args)
{
//参数签名算法测试例子
HashMap<String, String> signMap = new HashMap<String, String>();
signMap.put("appkey",appKeyId);
signMap.put("random_str","haxf");
String dateStr = (new Date()).getTime()+"";
signMap.put("timestamp",dateStr);
System.out.println("得到签名sign1:"+getSign(signMap,secretKey));
StringBuffer sb = new StringBuffer("http://localhost:8080/dome/api/v2/getUser?appkey="+appKeyId);
sb.append("×tamp=").append(dateStr).append("&random_str=vdedg").append("&sign=").append(getSign(signMap,secretKey));
System.out.println(sb.toString());
}
外部接口签名验证:
public static boolean checkSign(HttpServletRequest request,HttpServletResponse response){
ApiModel apiModel = new ApiModel();
String appid = request.getParameter("appkey");//appid
String sign = request.getParameter("sign");//签名
String random_str = request.getParameter("random_str");//签名
String timestamp = request.getParameter("timestamp");//时间戳
if(appid==null ||sign==null||timestamp==null||random_str==null) {
apiModel.info(401,"鉴权失败,缺少鉴权参数,请检查!");
print(response, apiModel);
return false;
}
if(!appid.equals(appKeyId)){
apiModel.info(401,"appId 不正确!");
print(response, apiModel);
return false;
}
//check时间戳的值是否在当前时间戳前后一小时以内
String currTimestamp = String.valueOf(new Date().getTime() / 1000); // 当前时间的时间戳
int currTimestampNum = Integer.parseInt(currTimestamp);
long verifyTimestampNum = Long.valueOf(timestamp)/1000; // 时间戳的数值
// 在5分钟范围之外,访问已过期
if (Math.abs(verifyTimestampNum - currTimestampNum) > 300) {
apiModel.info(401,"sigin已经过期");
print(response, apiModel);
return false;
}
检查sigin是否过期:
//Enumeration<?> pNames = request.getParameterNames();
Map<String, String> params = new HashMap<String, String>();
// while (pNames.hasMoreElements()) {
// String pName = (String) pNames.nextElement();
// if("sign".equals(pName)) continue;
// String pValue = (String)request.getParameter(pName);
// params.put(pName, pValue);
// }
params.put("appkey", appid);
params.put("random_str", random_str);
params.put("timestamp", timestamp);
if(!sign.equals(getSign(params, secretKey))){
apiModel.info(401,"sigin不正确。");
print(response, apiModel);
return false;
}
return true;
}
public static String utf8Encoding(String value, String sourceCharsetName) {
try {
return new String(value.getBytes(sourceCharsetName), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
}
private static byte[] getMD5Digest(String data) throws IOException {
byte[] bytes = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
bytes = md.digest(data.getBytes("UTF-8"));
} catch (GeneralSecurityException gse) {
throw new IOException(gse);
}
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();
}
得到签名:
public static String getSign(Map<String, String> params,String secret)
{
String sign="";
StringBuilder sb = new StringBuilder();
//step1:先对请求参数排序
Set<String> keyset=params.keySet();
TreeSet<String> sortSet=new TreeSet<String>();
sortSet.addAll(keyset);
Iterator<String> it=sortSet.iterator();
//step2:把参数的key value链接起来 secretkey放在最后面,得到要加密的字符串
while(it.hasNext())
{
String key=it.next();
String value=params.get(key);
sb.append(key).append("=").append(value).append("&");
}
sb.append("secretkey=").append(secret);
byte[] md5Digest;
try {
//得到Md5加密得到sign
md5Digest = getMD5Digest(sb.toString());
sign = byte2hex(md5Digest);
} catch (IOException e) {
LOGGER.error("生成签名错误",e);
}
return sign;
}
响应内容:
public static void print(HttpServletResponse response, Object obj) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
Gson gson = new GsonBuilder().serializeNulls().create();
out.print(gson.toJson(obj));
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
时间是企鹅:2059年9155月07日