懒洋洋的猫
发布于 2025-07-29 / 2 阅读
0

基于HmacSHA256实现的签名算法

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