JAVA接口签名sign生成工具类

2022-09-16 09:38:18

 签名规则

       1、线下分配appid和appsecret,针对不同的调用方分配不同的appid和appsecret

  2、加入timestamp(时间戳),10分钟内数据有效

  3、加入流水号nonce(防止重复提交),至少为10位。

  4、加入signature,所有数据的签名信息。

1.pom

       <!--DigestUtils依赖-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>

2.签名生成工具类


import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;


public class SignUtils {


    private SignUtils() {
    }

    public static String getTimestamp() {
        //生成时间戳
        long timestampLong = System.currentTimeMillis();
        String timestampStr = String.valueOf(timestampLong);

        return timestampStr;
    }


    public  static String getNonceStr(int length) {

        //生成随机字符串
        String str = "zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        Random random = new Random();
        StringBuffer randomStr = new StringBuffer();
        // 设置生成字符串的长度,用于循环
        for (int i = 0; i < length; ++i) {
            //从62个的数字或字母中选择
            int number = random.nextInt(62);
            //将产生的数字通过length次承载到sb中
            randomStr.append(str.charAt(number));
        }
        //将承载的字符转换成字符串
        return randomStr.toString();
    }



    /*
     * @Date 2021/6/30 11:21
     * @Param [params, privateKey 私钥]
     * @Return java.lang.String
     * @Desc 签名生成方法
     *
     */
    public static String createSign(Map<String, String> params, String privateKey) {

        StringBuilder sb = new StringBuilder();
        // 将参数以参数名的字典升序排序
        Map<String, String> sortParams = new TreeMap<String, String>(params);
        // 遍历排序的字典,并拼接"key=value"格式
        for (Map.Entry<String, String> entry : sortParams.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue().trim();
            if (!StringUtils.isEmpty(value))
                sb.append("&").append(key).append("=").append(value);
        }
        String stringA = sb.toString().replaceFirst("&", "");
        // String privateKey = "WHJBK24NXCX"; //私钥最后放在配置文件里面读取
        String stringSignTemp = stringA + "&" + "appkey=" + privateKey;
        //将签名使用MD5加密并全部字母变为大写
        // String signValue = Md5Encrypt.md5(stringSignTemp).toUpperCase();
        String signValue = DigestUtils.md5Hex(stringSignTemp+ getTimestamp());

        System.out.println("stringA+privateKey后MD5加密+转换全部大写生成sign为:       " + signValue);
        return signValue;
    }

    public static void main(String[] args) {

        Map<String, String> params = new HashMap<>();
        params.put("getNonceStr",getNonceStr(1024));

        SignUtils.createSign(params, "@@@@@@@```11");

       // System.out.println(SignUtils.getNonceStr(11));
    }

需要的jar包

         <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

生成相关的key


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

public class AccessKeyUtil {


    private static final String ALGORITHM_MD5 = "md5";
    private static final String CHARSET = "UTF-8";
    private static final String ALGORITHM_HMACSHA256 = "HmacSHA256";


    private AccessKeyUtil() {
    }

    /**
     * 生成签名
     *
     * @param obj
     * @param secretKey
     * @return
     */
    public static String generateSignature(Object obj, String secretKey) {
        String jsonString = JSONObject.toJSONString(obj, SerializerFeature.SortField);
        return encrypt(jsonString, secretKey);
    }

    /**
     * 编码
     *
     * @param encodeString
     * @param secretKey
     * @return
     */
    private static String encrypt(String encodeString, String secretKey) {
        try {
            Mac mac = Mac.getInstance(ALGORITHM_HMACSHA256);
            mac.init(new SecretKeySpec(secretKey.getBytes(), ALGORITHM_HMACSHA256));
            byte[] cryToGraph = mac.doFinal(encodeString.getBytes(CHARSET));
            //通过Base64编码为ASCII字符后传输
            return Base64.encodeBase64String(cryToGraph);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成SecretKey
     *
     * @param key
     * @return
     */
    public static String generateSecretKey(String key) {
        return getAESKeyBytes(key);
    }

    /**
     * 生成AccessKey
     *
     * @param key
     * @return
     */
    public static String generateAccessKey(String key) {
        return getAESKeyBytes(key);
    }

    /**
     * 根据字符串生成AES的密钥字节数组<br>
     */
    private static String getAESKeyBytes(String key) {
        try {
            MessageDigest md = MessageDigest.getInstance(ALGORITHM_MD5);
            md.update(key.getBytes(CHARSET));
            byte[] md5Bytes = md.digest();
            StringBuffer hexValue = new StringBuffer();
            for (int i = 0; i < md5Bytes.length; i++) {
                int val = ((int) md5Bytes[i]) & 0xff;
                if (val < 16) {
                    hexValue.append("0");
                }
                hexValue.append(Integer.toHexString(val));
            }
            return hexValue.toString();
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static synchronized Long generate() {
        Long time = (new Date()).getTime();
        String timeStr = Long.toString(time);
        int length = timeStr.length();
        Random random = new Random();
        int lastStr = (int) ((double) random.nextFloat() * Math.pow(10.0D, (double) (16 - length)));
        Long id = Long.parseLong(timeStr + lastStr);
        return id;
    }

    public static String generateString(String prefix) {
        return prefix + UUID.randomUUID().toString().replaceAll("-", "");
    }


    /**
     * @Desc 生成appkey
     * @Param [key] 参数
     */
    public static String generateAppKey(String key) {

        if (StringUtils.isBlank(key)) {
            return null;
        }

        StringBuilder builder = new StringBuilder();
        builder.append(key);
        builder.append(":");
        builder.append(AccessKeyUtil.generateString(""));
        String appKey = builder.toString();
        return DigestUtils.md5Hex(appKey);
    }

    public static void main(String[] args) {


        String appKey = AccessKeyUtil.generateAppKey("123");
        String accessKey = AccessKeyUtil.generateAccessKey("123");
        String secretKey = AccessKeyUtil.generateSecretKey("123" + ":secretKey");

        System.out.println("appKey--->" + appKey);
        System.out.println("accessKey--->" + accessKey);
        System.out.println("secretKey--->" + secretKey);
    }

}

sign生成一般 appId或请求参数+appKey+accessKey+secretKey+请求时的时间戳

sign      由DigestUtils.md5Hex(appKey+accessKey+ secretKey+ timestamp ) 生成

  • 作者:人生就像一场戏!
  • 原文链接:https://blog.csdn.net/qq_40428665/article/details/118357865
    更新时间:2022-09-16 09:38:18