签名认证工具类

该代码示例展示了如何在Java中使用ApacheCommonsLang和SLF4J库创建一个SignUtils类,该类用于生成和校验基于HMAC-SHA256算法的签名。类中包含了时间戳和随机字符串的验证,以及签名的生成和校验方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值