import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* <p>
* <code>SignUtils</code>
* </p>
* Description:
*
*/
@Slf4j
public class SignUtils {
/**
* 时间差,最长
*/
private static final long MAX_TIMESTAMP_DIFFERENCE = 5 * 60 * 1000;
/**
* 时间差,最短
*/
private static final long MIN_TIMESTAMP_DIFFERENCE = 5 * 60 * 1000;
/**
* 随机字符串长度,最长
*/
public static final int MAX_NONCE_LENGTH = 50;
/**
* 随机字符串长度,最短
*/
public static final int MIN_NONCE_LENGTH = 30;
public static void main(String[] args) {
String appId = RandomStringUtils.randomAlphanumeric(MIN_NONCE_LENGTH);
String appSecret = RandomStringUtils.randomAlphanumeric(MAX_NONCE_LENGTH);
// 也可以使用uuid等
String nonce = RandomStringUtils.randomAlphanumeric(RandomUtils.nextInt(MIN_NONCE_LENGTH, MAX_NONCE_LENGTH));
long timestamp = System.currentTimeMillis();
String auth = "这里是业务信息,例如json请求参数:{\"id\":\"1\"}";
String sign = SignUtils.getSign(auth, nonce, timestamp, appId, appSecret);
boolean check = SignUtils.checkSign(auth, nonce, timestamp, sign, appId, appSecret);
System.out.println("==>appId:" + appId);
System.out.println("==>appSecret:" + appSecret);
System.out.println("==>nonce:" + nonce);
System.out.println("==>timestamp:" + timestamp);
System.out.println("==>sign:" + sign);
System.out.println("==>check:" + check);
}
/**
* 获取签名
*/
public static String getSign(String auth, String nonce, long timestamp, String appId, String appSecret) {
// TODO 业务自行判断是否过期
// if ((System.currentTimeMillis() - timestamp > MAX_TIMESTAMP_DIFFERENCE) || (timestamp - System.currentTimeMillis() > MIN_TIMESTAMP_DIFFERENCE)) {
// throw new IllegalArgumentException("非法参数");
// }
if (StringUtils.isAnyBlank(auth, nonce, appId, appSecret)
|| nonce.length() < MIN_NONCE_LENGTH || nonce.length() > MAX_NONCE_LENGTH) {
throw new IllegalArgumentException("非法参数");
}
try {
Mac mac = Mac.getInstance("hmacsha256");
mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256"));
byte[] bytes = mac.doFinal((appId + auth + nonce + timestamp).getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
log.error("==>生成签名失败,appId:{},nonce:{},timestamp:{}", appId, nonce, timestamp, e);
throw new RuntimeException(e);
}
}
/**
* 校验签名
*/
public static boolean checkSign(String auth, String nonce, long timestamp, String sign, String appId, String appSecret) {
return getSign(auth, nonce, timestamp, appId, appSecret).equalsIgnoreCase(sign);
}
}
签名认证工具类
于 2023-06-05 14:10:32 首次发布