MD5 参数签名算法

在HTTP POST 或者 HTTP GET的接口请求时,为了繁殖数组被篡改,保证数据的安全性,通常会添加签名参数,下面给出一个基于MD5实现的签名参数的代码:

package cn.tim;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

/** * 产生Md5产生签名的方法 */
public class GenSignTest {

    public static void main(String[] args) {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("best", "morning");
        params.put("appName", "tencent");
        params.put("appValue", "1024");
        String secretKey = "1024";
        String sign = genSign(params, secretKey);
        System.out.println(sign);

    }

    public static String genSign(HashMap<String, String> params, String secretKey){
        //将参数以参数名的字典升序排序
        Map<String, String> sortParams = new TreeMap<String, String>(params);
        Set<Entry<String, String>> entrys = sortParams.entrySet();

        //遍历排序的字典,并拼接"key=value"格式
        StringBuilder baseString = new StringBuilder();
        for(Entry<String, String> entry:entrys){
            baseString.append(entry.getKey()).append("=").append(entry.getValue());
        }
        baseString.append(secretKey);

        //使用MD5对待签名串求签
        byte[] bytes = null;
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
            try {
                bytes = md5.digest(baseString.toString().getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //将MD5输出的二进制结果转换为小写的十六进制
        StringBuilder sign = new StringBuilder();
        for(int i=0;i<bytes.length;i++){
            String hex = Integer.toHexString(bytes[i]&0xFF);
            if(hex.length() == 1){
                sign.append("0");
            }
            sign.append(hex); 
        }
        return sign.toString();
    }
}

注意:上面的代码中有两个小技巧:
1、//将参数以参数名的字典升序排序

Map<String, String> sortParams = new TreeMap<String, String>(params);
  TreeMap函数的作用官方的原文是:
  Constructs a new tree map containing the same mappings as the given map, ordered according to the natural ordering of its keys. All keys inserted into the new map must implement the Comparable interface. Furthermore, all such keys must be mutually comparable: k1.compareTo(k2) must not throw a ClassCastException for any keys k1 and k2 in the map. This method runs in n*log(n) time.
  翻译成中文:根据键的自然自然书序(即升序)构造一个新的树形的树映射。所有这些键都必须根据上面的比较接口来插入构成一个新的映射。...
Set<Entry<String, String>> entrys = map.entrySet();
for(Entry<String, String> entry:entrys){ entry.getKey(); entry.getValue(); }

上面这个方法也是经常用到的,可以在不知道key的情况,遍历取出所有的key对应的value值。

补充:
在实际开发中,为了进一步加强信息安全,通常会将要传递的url参数进行编码,以及加上自定义的字符串,在接收端,先去掉自定义的字符串,在解码即可。

【参考文献】:
1、http://www.cnblogs.com/taoweiji/p/3496697.html

你可能感兴趣的:(加密)