基於webservice實現的安全通信架構

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