Java接口签名和验签
Java接口签名和验签
import com.alibaba.fastjson.JSON; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field; import java.util.*; public class Signature { /** * 签名 * @param object * @param key * @return * @throws Exception */ public static String getSign(Object object,String key) throws Exception { Map<String, String> map = objectToMap(object); return getSign(map,key); } private static Map<String, String> objectToMap(Object object) { Map<String,String> map = new HashMap<>(); Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); map.put(field.getName(), String.valueOf(field.get(object))); }catch (Exception e) { e.printStackTrace(); } } return map; } /** * 签名 * @param map * @param key * @return * @throws Exception */ public static String getSign(Map<String,String> map,String key) throws Exception{ ArrayList<String> list = new ArrayList<String>(); for(Map.Entry<String,String> entry:map.entrySet()){ if(entry.getValue() != null && StringUtils.isNotBlank(entry.getValue().toString()) && !"null".equals(entry.getValue()) && !"class".equals(entry.getKey()) && !"data".equals(entry.getKey())){ //空字符串 entry.getValue()!=""){ list.add(entry.getKey() + "=" + entry.getValue() + "&"); } } int size = list.size(); String [] arrayToSort = list.toArray(new String[size]); Arrays.sort(arrayToSort); StringBuilder sb = new StringBuilder(); for(int i = 0; i < size; i ++) { sb.append(arrayToSort[i]); } String result = sb.toString(); //过滤最后一个字符串& int lastIdx = result.lastIndexOf("&"); result = result.substring(0,lastIdx); result += key; try{ result = MD5.MD5Encode(result).toUpperCase(); }catch (Exception e) { e.printStackTrace(); } return result; } /** * 验签 * @param object * @param key * @return * @throws Exception */ public static boolean checkIsSignValidFromResyponseStringObject(Object object,String key) throws Exception { Map<String, String> map = objectToMap(object); return checkIsSignValidFromResponseString(map,key); } /** * 验签 * @param map * @param key * @return * @throws Exception */ public static boolean checkIsSignValidFromResponseString(Map<String,String> map,String key) throws Exception { String signFromAPIResponse = null; if(map.get("sign")!=null){ signFromAPIResponse = map.get("sign").toString(); } if(signFromAPIResponse=="" || signFromAPIResponse == null){ return false; } //清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名 map.put("sign",""); map.put("class",""); //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较 //重新签名 String signForAPIResponse = Signature.getSign(map,key); if(!signForAPIResponse.equals(signFromAPIResponse)){ //签名验不过,表示这个API返回的数据有可能已经被篡改了 return false; } return true; } //test static class UserInfo{ private String userName; private String idNo; private String mobile; private String sign; public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getIdNo() { return idNo; } public void setIdNo(String idNo) { this.idNo = idNo; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } } /** * 签名字符串:84CBF6035C54EAFE62E3F57F1737C733 * 参数json={"idNo":"463300122545556699","mobile":"19966667777","sign":"84CBF6035C54EAFE62E3F57F1737C733","userName":"张三"} * 验证签名是否一致=true * @param args */ public static void main(String[] args) { try { String key = "testkey111"; UserInfo userInfo = new UserInfo(); userInfo.setMobile("19966667777"); userInfo.setUserName("张三"); userInfo.setIdNo("463300122545556699"); String signStr = Signature.getSign(userInfo,key); System.out.println("签名字符串:" + signStr); userInfo.setSign(signStr); System.out.println("参数json=" + JSON.toJSONString(userInfo)); //验证签名 boolean flag = Signature.checkIsSignValidFromResyponseStringObject(userInfo,key); System.out.println("验证签名是否一致="+flag); } catch (Exception e) { e.printStackTrace(); } } }
import java.security.MessageDigest; public class MD5 { private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; /** * 转换字节数组为16进制字串 * @param b 字节数组 * @return 16进制字串 */ public static String byteArrayToHexString(byte[] b) { StringBuilder resultSb = new StringBuilder(); for (byte aB : b) { resultSb.append(byteToHexString(aB)); } return resultSb.toString(); } /** * 转换byte到16进制 * @param b 要转换的byte * @return 16进制格式 */ private static String byteToHexString(byte b) { int n = b; if (n < 0) { n = 256 + n; } int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } /** * MD5编码 * @param origin 原始字符串 * @return 经过MD5加密之后的结果 */ public static String MD5Encode(String origin) { String resultString = null; try { resultString = origin; MessageDigest md = MessageDigest.getInstance("MD5"); resultString = byteArrayToHexString(md.digest(resultString.getBytes())); } catch (Exception e) { e.printStackTrace(); } return resultString; } }