关于md5的加密

前段时间,由于工作需要,首次接触md5加密 (接触的有点晚)

本次需求主要是对接淘宝保险产品,我们将产品发布到淘宝商城上进行销售,客户进行购买后,我们为其完成核保、承保的相关工作。因为是两个系统之间的对接,所有牵扯报文交互。

对接系统:淘宝商城,寿险网销系统

交互协议:http请求

数据格式 :xml 报文

加密机制:

        在我未拿到相关的文档的时候,我以为一定是一种非常酷的加密方式,毕竟牵扯的双方都是业界大拿,雄踞乙方的商业霸主,但是拿到具体的文档后,着实大跌眼镜。

    发送方对报文进行(MD5)加签,接收方同样对报文进行加签,然后对签名进行比较

    注意MD5是不可逆 ,加密之后就是一个字符串 ,所有淘宝 需要把签名和xml 报文一起传过来 ,然后 接收方在按照共同的公钥 ,(公钥+xml)进行加签(是不是low)

     不过在研发的过程中发现了一个有意思的事 :

   一个http请求,既可以是post请求,也可以使get请求,大家不妨一试

扫描二维码关注公众号,回复: 1007958 查看本文章

     另外,有一点值得注意的是,在加密的过程中,如果含有中文,那么编码格式是非常重要的,在加签名的过程中,中文的格式将影响到最后密文

具体代码如下 

public class SignUtil {
	private static String key=null;//Configuration.getValue("tmall.comId");
	
	private static String encoding="GBK";
	
	private static final FormatLogger log = new FormatLogger(SignUtil.class);
	
	public static void setKey(String key){
		SignUtil.key = key; 
	}
	public static String readXmlFromInputStream(ServletInputStream sis) throws Exception{
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = sis.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}

		String requestXml = new String(outSteam.toByteArray(), encoding);
		log.info("SignUtil-readXmlFromInputStream-requestXml:"+requestXml);
		return requestXml;
	}
	
	public static boolean validateSign(String requestXml, String sign) throws IOException, NoSuchAlgorithmException{
		MessageDigest md = MessageDigest.getInstance("MD5");
		md.update(key.getBytes(encoding));
		md.update(requestXml.getBytes(encoding));
		byte[] bs = md.digest();
		
		String resultStr = bytes2HexString(bs);
		boolean flag = sign.equals(resultStr);
		log.info("SignUtil-validateSign-key:" + key + " resultStr:"+resultStr + " return:" + flag);
		
		return flag;
	}
	
	public static String sign(String data) throws NoSuchAlgorithmException, UnsupportedEncodingException{
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(key.getBytes(encoding));
        md.update(data.getBytes(encoding));
        return asHex(md.digest());
	}
	
	public static String asHex (byte hash[]) {
        StringBuffer buf = new StringBuffer(hash.length * 2);
        int i;

        for (i = 0; i < hash.length; i++) {
          if (((int) hash[i] & 0xff) < 0x10) 
        buf.append("0");

          buf.append(Long.toString((int) hash[i] & 0xff, 16));
        }

        return buf.toString();
     }
	
	public final static String MD5(String s) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'A', 'B', 'C', 'D', 'E', 'F' };
		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	 
	public static String bytes2HexString(byte[] b) {
		StringBuffer result = new StringBuffer();
		String hex;
		for (int i = 0; i < b.length; i++) {
			hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			result.append(hex);
		}
		return result.toString();
	} 

猜你喜欢

转载自my.oschina.net/u/198077/blog/1787084