package com.hfkj.common.utils; import com.alipay.api.internal.util.StringUtils; import com.taobao.top.Constants; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.util.Arrays; import java.util.Map; public class TaoBaoUtil { public static String signTopRequest(Map params, String secret, String signMethod) throws IOException { // 第一步:检查参数是否已经排序 String[] keys = params.keySet().toArray(new String[0]); Arrays.sort(keys); // 第二步:把所有参数名和参数值串在一起 StringBuilder query = new StringBuilder(); if (Constants.SIGN_METHOD_MD5.equals(signMethod)) { //签名的摘要算法,可选值为:hmac,md5,hmac-sha256 query.append(secret); } for (String key : keys) { String value = params.get(key); if (StringUtils.areNotEmpty(key, value)) { query.append(key).append(value); } } // 第三步:使用MD5/HMAC加密 byte[] bytes; if (Constants.SIGN_METHOD_HMAC.equals(signMethod)) { bytes = encryptHMAC(query.toString(), secret); } else { query.append(secret); bytes = encryptMD5(query.toString()); } // 第四步:把二进制转化为大写的十六进制(正确签名应该为32大写字符串,此方法需要时使用) return byte2hex(bytes); } // 将字节数组转换为十六进制字符串 public static String byte2hex(byte[] bytes) { // 创建一个StringBuilder对象,用于存储转换后的十六进制字符串 StringBuilder sign = new StringBuilder(); // 遍历字节数组 for (byte aByte : bytes) { // 将字节数组中的每个字节转换为十六进制字符串 String hex = Integer.toHexString(aByte & 0xFF); // 如果转换后的十六进制字符串长度为1,则在前面补0 if (hex.length() == 1) { sign.append("0"); } // 将转换后的十六进制字符串转换为大写,并添加到StringBuilder对象中 sign.append(hex.toUpperCase()); } // 返回转换后的十六进制字符串 return sign.toString(); } // 加密HMAC public static byte[] encryptHMAC(String data, String secret) throws IOException { // 声明一个字节数组 byte[] bytes = null; try { // 创建一个SecretKey对象,使用secret和Constants.CHARSET_UTF8编码 SecretKey secretKey = new SecretKeySpec(secret.getBytes(Constants.CHARSET_UTF8), "HmacMD5"); // 获取Mac实例 Mac mac = Mac.getInstance(secretKey.getAlgorithm()); // 初始化Mac对象 mac.init(secretKey); // 使用Mac对象对data进行加密,使用Constants.CHARSET_UTF8编码 bytes = mac.doFinal(data.getBytes(Constants.CHARSET_UTF8)); } catch (GeneralSecurityException gse) { // 抛出IOException异常 throw new IOException(gse.toString()); } // 返回加密后的字节数组 return bytes; } // 加密MD5 public static byte[] encryptMD5(String data) throws IOException { // 将字符串转换为字节数组 return encryptMD5(data.getBytes(Constants.CHARSET_UTF8)); } // 加密数据为MD5 public static byte[] encryptMD5(byte[] data) throws IOException { // 声明一个字节数组,用于存储加密后的数据 byte[] bytes = null; try { // 获取MD5加密算法实例 MessageDigest md = MessageDigest.getInstance("MD5"); // 对数据进行加密 bytes = md.digest(data); } catch (GeneralSecurityException gse) { // 如果发生异常,则抛出IO异常 throw new IOException(gse.toString()); } // 返回加密后的数据 return bytes; } }