package com.albert.scanner;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class SignTools {
/**
* 创建签名
* @param timestamp
* @param secret
* @return
* @throws Exception
*/
public static String createSign(Long timestamp, String secret) throws Exception {
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
return sign;
}
/**
* 验证签名
* @param appId
* @param sign
* @param timestamp
* @return
* @throws Exception
*/
public static boolean validateSign(String appId, String sign, Long timestamp) throws Exception {
// timestamp
if (System.currentTimeMillis() - timestamp > 1000 * 30) {
throw new RuntimeException("timestamp is invalid");
}
String secretKey = secretKeyMap.get(appId);
String serverSign = createSign(timestamp, secretKey);
if (serverSign.equals(sign)) {
return true;
}
return false;
}
/**
* 服务器记录不同的appId对应的appSecret私钥
*/
static Map<String, String> secretKeyMap = new HashMap<>();
public static void main(String[] args) throws Exception {
secretKeyMap.put("xxx", "0dfDafa&_8870==");
Long timeStamp = System.currentTimeMillis();
String appId = "xxx";
String secretKey = "0dfDafa&_8870==";
// 客户端请求的时候,输入签名
String sign = createSign(System.currentTimeMillis(), secretKey);
// 服务端验证签名
System.out.println(validateSign(appId, sign, timeStamp));
}
}