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 = "12345xxxxxx";


        System.out.println("第一种方式:调用org.apache.commons.codec.digest.DigestUtils;");
        String sign1 = DigestUtils.md5Hex(str);
        System.out.println("第一次md5加密的字符串是");
        System.out.println("第一次md5加密后转大写的");
        System.out.println(sign1);
        System.out.println(sign1.toUpperCase());


        System.out.println("第一种方式:调用jdk中自带的java.security.MessageDigest,需要抛几个异常");
        MessageDigest md = MessageDigest.getInstance("MD5");
        System.out.println(md.toString());
        md.update(str.getBytes("UTF-8"));
        System.out.println(md.toString());
        byte[] bytes = md.digest(); //encryptMD5(strtemp);
        System.out.println(bytes);

        /**
         *  二进制转化为大写的十六进制
         * @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);

        StringBuilder sign3 = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String singdata = String.format("%2s", Integer.toHexString(bytes[i] & 0xFF).toUpperCase()).replace(\' \', \'0\');

            sign3.append(singdata);
        }
        String result3 = sign3.toString();
        System.out.println(result3);
        // 把 BYTE  类型 转化为十六进大写字符串 HEX,并在最左补齐0,方法如下。
        //String singdata = String.format("%2s", Integer.toHexString(mdata & 0xFF).toUpperCase()).replace(\' \', \'0\');
    }
}

  

“C:\Program Files\Java\jdk1.8.0_172\bin\java.exe” “-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\lib\idea_rt.jar=41471:C:\Program Files\JetBrains\IntelliJ IDEA 2018.1.5\bin” -Dfile.encoding=UTF-8 -classpath “C:\Program Files\Java\jdk1.8.0_172\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_172\jre\lib\rt.jar;D:\00M_IDEA_Project\encrypt\out\production\encrypt;D:\00M_IDEA_Project\encrypt\jar\commons-codec-1.11.jar” Test
第一种方式:调用org.apache.commons.codec.digest.DigestUtils;
第一次md5加密的字符串是
第一次md5加密后转大写的
c1005a2f48f6e4242fa973960ae74452
C1005A2F48F6E4242FA973960AE74452
第一种方式:调用jdk中自带的java.security.MessageDigest,需要抛几个异常
MD5 Message Digest from SUN, <initialized>

MD5 Message Digest from SUN, <in progress>

[B@63947c6b
C1005A2F48F6E4242FA973960AE74452
C1005A2F48F6E4242FA973960AE74452

 

  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

 

版权声明:本文为qianjinyan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/qianjinyan/p/10727804.html