關於md5的加密

前段時間,因爲工做須要,首次接觸md5加密 (接觸的有點晚)git

本次需求主要是對接淘寶保險產品,咱們將產品發佈到淘寶商城上進行銷售,客戶進行購買後,咱們爲其完成核保、承保的相關工做。由於是兩個系統之間的對接,全部牽扯報文交互。算法

對接系統:淘寶商城,壽險網銷系統app

交互協議:http請求post

數據格式 :xml 報文編碼

加密機制:加密

        在我未拿到相關的文檔的時候,我覺得必定是一種很是酷的加密方式,畢竟牽扯的雙方都是業界大拿,雄踞乙方的商業霸主,可是拿到具體的文檔後,着實大跌眼鏡。spa

    發送方對報文進行(MD5)加簽,接收方一樣對報文進行加簽,而後對簽名進行比較code

    注意MD5是不可逆 ,加密以後就是一個字符串 ,全部淘寶 須要把簽名和xml 報文一塊兒傳過來 ,而後 接收方在按照共同的公鑰 ,(公鑰+xml)進行加簽(是否是low)orm

     不過在研發的過程當中發現了一個有意思的事 :xml

   一個http請求,既能夠是post請求,也可使get請求,你們不妨一試

     另外,有一點值得注意的是,在加密的過程當中,若是含有中文,那麼編碼格式是很是重要的,在加簽名的過程當中,中文的格式將影響到最後密文

具體代碼以下 

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();
	}
相關文章
相關標籤/搜索