接口中的签名加密方式

2019-04-18
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Map;

import org.springframework.util.StringUtils;

public class SignUtil {
	
	public static String signTopRequest(Map<String, Object> params, String secret) throws Exception{
		
   		// 第一步:检查参数是否已经排序
		String[] keys = params.keySet().toArray(new String[0]);
		Arrays.sort(keys);	
		// 第二步:把所有参数名和参数值串在一起
		StringBuilder query = new StringBuilder();
		
		for (String key : keys) {
		    String value = replaceNullStr(params.get(key));
		    if (!StringUtils.isEmpty(key)&&!StringUtils.isEmpty(value)) {
		    	if("sign".equals(key)){
		    		continue;
		    	}
		        query.append(key).append(CONST.CONNECT_EQUAL).append(value).append(CONST.CONNECT_AND);
		    }
		}
		String strtemp = null;
		if(query.length()>0){
			strtemp = query.substring(0, query.lastIndexOf(CONST.CONNECT_AND));
		}
		// 第三步:使用MD5加密
		byte[] bytes;
		strtemp = strtemp + secret;
		System.out.println(strtemp);
		bytes = encryptMD5(strtemp);
		// 第四步:把二进制转化为大写的十六进制
//		return new String(bytes,"UTF-8");
		return byte2hex(bytes);
    }

   	
   	private static String replaceNullStr(Object str) {
   		if(str == null){
   			return "";
   		}
   		return str.toString();
   	}


	/**
   	 * 加密
   	 * @param data
   	 * @return
   	 */
   	private static byte[] encryptMD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(data.getBytes("UTF-8"));
        return md.digest();
    }
   	
   	/**
   	 *  二进制转化为大写的十六进制
   	 * @param bytes
   	 * @return
   	 */
   	public static String byte2hex(byte[] bytes) {
        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.toUpperCase());
        }
        return sign.toString();
    }


}

  

import org.apache.commons.codec.digest.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Test {

    public static void main(String args[]) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        String str = "brand_id=MB1000000000001&scene_str=ddsd...";
        String sign1 = DigestUtils.md5Hex(str);
        System.out.println("第一次md5加密的字符串是");
        System.out.println("第一次md5加密后转大写的");
        System.out.println(sign1);
        System.out.println(sign1.toUpperCase());

        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(sign1.getBytes("UTF-8"));
        byte[] bytes = md.digest(); //encryptMD5(strtemp);


        /**
         *  二进制转化为大写的十六进制
         * @param bytes
         * @return
         */

        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.toUpperCase());
        }
        String result = sign.toString();
        System.out.println(result);
    }
}

  

一、  MD5签名

1.         参与签名参数数组

在请求参数列表中,除去sign参数外,其他需要使用到的参数(参数值为空或空字符串除外)皆是要签名的参数。

例如下的签名参数:

brand_id=MB1000000000001

scene_str=card_center

timestamp=1504688298167

user_id=ksXMQfCgMAPT5GhKuGoTJTeFN7rxYDUdQNmfIfTUWtnGbg+IZPYBarluhEZKR1wYJS2h4odHkXhusDb49ysYbleBXH2ScnfmP9GfWVs9lKXgZXqFzkdPqxhLN3fmIV/cx3l4DCMsCHy5dmrZLmufPeUnNY/IIYG8k6+vVd3DiEc=

 

签名秘钥:

sign_key=”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”

2.         生成代签名的字符串

将所有参与签名的参数名按照字典排序(每一个参数名按照a-z的顺序排序),若遇到相同的首字母,则看第二个字母,以此类推。排序完成后,再把数组所有参数按照“参数=参数值用”的模式用“&”字符拼接成字符串,并在得到的字符串最后拼接上签名秘钥sign_key得到待签名字符串signTempStr。

signTempStr=“brand_id=MB1000000000001&scene_str=card_center&timestamp=1504688298167&user_id=ksXMQfCgMAPT5GhKuGoTJTeFN7rxYDUdQNmfIfTUWtnGbg+IZPYBarluhEZKR1wYJS2h4odHkXhusDb49ysYbleBXH2ScnfmP9GfWVs9lKXgZXqFzkdPqxhLN3fmIV/cx3l4DCMsCHy5dmrZLmufPeUnNY/IIYG8k6+vVd3DiEc= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”

 

3.         MD5签名

把上面得到的代签名字符串使用MD5进行签名,并转为大写字母得到最后的签名串sign值。

String sign = MD5(signTempStr) = 782200BEFC4BB3C37E6F35C53BBFE34E