一、MD5签名与验签
MD5全名Message-Digest Algorithm 5(信息-摘要算法)是一种不可逆的加密算法。
MD5算法具有以下特点:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
MD5生成签名和验签需要MD5 key,这个key值就是一段字符串没有任何限制比如:123456ADSEF
2.签名与验签流程
首先参数放入一个字符串数组signFields,把参数和值放入一个对象或map中,使用JSONObject把这个对象转化成json对象。
然后构建签名原文,在构建签名原文时,我们需把参数按照字典(比如a,b,c)顺序排序,具体排序方法直接调java的Arrays.sort方法。
然后按照key=value的方式把所有参数和值拼接成字符串,多个参数直接以“&”符号隔开,再然后把MD5 key拼接在该签名原文的最后。
最后使用MD5Encrypt.getMessageDigest(signSrc)生成签名。
验签很简单,验签方按照上面的签名流程生成的签名与传过来的签名作对比如果相等就验签成功,否则验签失败。
3.具体代码如下:
需验签的参数map:
MD5生成签名字符串:
/** * MD5生成签名字符串 * * @param map * 需签名参数 * @param key * MD5key * @return */ public static String MD5sign(Map<String, Object> map, String key) { String genSign = ""; try { String[] signFields = new String[5]; signFields[0] = "name"; signFields[1] = "age"; signFields[2] = "sex"; signFields[3] = "school"; signFields[4] = "address"; JSONObject param = (JSONObject) JSONObject.toJSON(map); // 生成签名原文 String signSrc = orgSignSrc(signFields, param); // MD5的方式签名 signSrc += "&KEY=" + key; genSign = MD5Encrypt.getMessageDigest(signSrc); } catch (Exception e) { e.printStackTrace(); } return genSign; }
构建签名原文:
/** * 构建签名原文 * * @param signFilds 参数列表 * @param param 参数与值的jsonbject * @return */ private static String orgSignSrc(String[] signFields, JSONObject param) { if (signFields != null) { Arrays.sort(signFields); // 对key按照 字典顺序排序 } StringBuffer signSrc = new StringBuffer(""); int i = 0; for (String field : signFields) { signSrc.append(field); signSrc.append("="); signSrc.append((StringUtil.isEmpty(param.getString(field)) ? "" : param.getString(field))); // 最后一个元素后面不加& if (i < (signFields.length - 1)) { signSrc.append("&"); } i++; } return signSrc.toString(); }
MD5验证签名:
/** * MD5验证签名 * @param map * @param key * @param sign * @return */ public static void vlidateMD5sign(Map<String ,Object> map,String key,String sign) { String vsign=MD5sign(map, key); System.out.println("MD5验证签名生成的签名:"+vsign); System.out.println("MD5验证签名生成的签名与原签名是否一致:sign=vsign true?false:"+(vsign.equals(sign))); }
main方法:
public static void main(String[] args) { Map<String ,Object> map=new HashMap<String,Object>(); map.put("name", "小明"); map.put("age", 12); map.put("sex", "男"); map.put("school", "xxx中学"); map.put("address", "xxx小区"); /***MD5签名与验签**/ String key="123456ADSEF"; String sign= MD5sign(map,key); System.out.println("生成的MD5签名:"+sign); vlidateMD5sign(map, key, sign) ; }
执行结果:
生成的MD5签名:A82ED0D0E0155D3926E0A6B6B3EE60C4 MD5验证签名生成的签名:A82ED0D0E0155D3926E0A6B6B3EE60C4 MD5验证签名生成的签名与原签名是否一致:sign=vsign true?false:true