本文demo下載地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1135java
【概述】web
本文基於webservice技術實現平臺架構, 此架構用於提供平臺服務,服務能夠用於客戶的對接以達到服務客戶的目的,而且保證服務過程當中的通信數據是安全的, 相似於 支付寶的支付服務,商家能夠申請相應的賬號和私密信息,用於完成支付操做而且保障信息的不可篡改, 但支付寶是經過RSA來校驗數據的安全性,而本文是使用md5來校驗數據, 客戶端與服務端的通信使用webservice, 以https形式進行交互, 本文假定你已經對axis的webservice的機制和使用有必定的瞭解算法
【流程】數據庫
1. 客戶向平臺服務申請AppID(axcpud123)和AppKeySecret(124jfj3ff3AjifLLefl)json
2. 客戶準備數據, 數據內容爲 telPhone=15261873121, userId=000001, idCert=32132219871234232數組
AppID+ & + (用戶數據內容按照key名稱從小到大排序) + & + AppKeySecret安全
對上面的數據進行MD5進行加密碼,生成密文 sign架構
3. 以axis webservice向服務端發送服務, 服務方法名 爲serverMethodapp
url_wsdl: https://域名/工程名/webservice名稱?wsdl @Override public String ysSignUrl(){ StringBuilder sb=new StringBuilder(); try{ String time=getTimeStr(); TestDTO data = new TestDTO(); data .setAppId(AppId); data .setTime(time); data .setTelPhone(phone); data .setUserId(userId); data .setIdCert(idCert); String j=JSON.toJSONString(data,true); JSONObject json=JSONObject.fromObject(j); String sortJson=commUtil.getSortStr(json,Constants.REGX); sb.append(sortJson).append(Constants.REGX).append(data.getAppSecretKey()); String sign=Md5Util.getMd5(sb.toString()); sb.setLength(0); sb.append(data.getYsUrl()).append(url_wsdl); Service service = new Service(); Call call=(Call)service.createCall(); call.setTargetEndpointAddress(new java.net.URL(sb.toString())); call.setOperationName(new QName("http://wsdl.com/", "serverMethod")); call.addParameter("appId", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("time", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("sign", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("telPhone", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("userId", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("idCert", XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); String result = call.invoke(new Object[] { data.getAppId(),time, sign, data.getTelPhone(), data.getUserId(), data.getIdCert() }).toString(); }catch(ServiceException se ){ }catch(MalformedURLException me){ }catch(RemoteException re){ }catch(Exception e){ return result; 4. webservice服務端接收到數據後,取出數據中的 AppID(axcpud123) telPhone=15261873121, userId=000001, idCert=32132219871234232, sign值 根據AppID到平臺數據庫中查找AppKeySecret(124jfj3ff3AjifLLefl), 而後對AppId, telPhone, userId, idCert,
AppKeySecret進行MD5加密 獲得signNew, 而後比較sign與signNew是否相同,若是相同,則認爲客戶端與服務端的通信數據未被修改dom
小知道點:
1. FastJson對json數據的key值按照a-z排序
public static String getSortStr(JSONObject json,String regx){ StringBuilder sortStr=new StringBuilder(); Iterator<String> iteratorKeys = json.keys(); SortedMap map = new TreeMap(); while (iteratorKeys.hasNext()) { String key = iteratorKeys.next().toString(); String vlaue = json.optString(key); map.put(key, vlaue); Set set = map.entrySet(); Iterator i = set.iterator(); while(i.hasNext()){ Map.Entry me = (Map.Entry)i.next(); String value=me.getValue().toString(); if(!value.isEmpty()){ sortStr.append(regx).append(value); return sortStr.substring(1,sortStr.length()); 2. MD5加密 .生成字符串MD5 .生成字節MD5 .生成文件的MD5值 /** * <p>Title: MD5Util.java</p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2018</p> * <p>Company: jsjn</p> * @author zhengwei * @date 2018年4月28日 * @version 1.0 */ package com.jsjn.slarms.extSysDock.common.util; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * <p>Title: MD5Util</p> * <p>Description: MD5算法</p> * @author zhengwei * @date 2018年4月28日 */ public class Md5Util { private static final String MD5="MD5"; private static final String UTF8="UTF-8"; private static final Integer LENGTH=1024; /** * <p>Title: getMd5</p> * <p>Description: 獲取MD5運算以後的值</p> * @param str * @return */ public final static String getMd5(String str) { MessageDigest mdInst = null; byte[] md=null; try { mdInst = MessageDigest.getInstance(MD5); /** * 使用指定的字節更新摘要 */ mdInst.update(str.getBytes(UTF8)); /** * 得到密文 */ md = mdInst.digest(); } catch (Exception e) { e.printStackTrace(); return byteArrToHexStr(md); private static String byteArrToHexStr(byte[] arrB) { int iLen = arrB.length; /** * 每一個byte(8位)用兩個(16進制)字符才能表示,因此字符串的長度是數組長度的兩倍 */ StringBuffer sb = new StringBuffer(iLen * 2); for (int i = 0; i < iLen; i++) { int intTmp = arrB[i]; /** * 把負數轉換爲正數 */ while (intTmp < 0) { intTmp = intTmp + 256; /** * 小於0F的數須要在前面補0 */ if (intTmp < 16) { sb.append("0"); sb.append(Integer.toString(intTmp, 16)); return sb.toString(); /** * <p>Title: getFileInputStreamMD5</p> * <p>Description: 計算文件流MD5值</p> * @param in * @return * @throws NoSuchAlgorithmException * @throws IOException */ public static String getFileInputStreamMD5(InputStream in) throws NoSuchAlgorithmException, IOException { MessageDigest digest = null; byte buffer[] = new byte[1024]; int len; digest = MessageDigest.getInstance(MD5); while ((len = in.read(buffer, 0, LENGTH)) != -1) { digest.update(buffer, 0, len); in.close(); BigInteger bigInt = new BigInteger(1, digest.digest()); return bigInt.toString(16);