作者微信 bishe2022

代码功能演示视频在页面下方,请先观看;如需定制开发,联系页面右侧客服
基于webservice实现的安全通讯架构

Custom Tab

【概述】

    本文基于webservice技术实现平台架构, 此架构用于提供平台服务,服务可以用于客户的对接以达到服务客户的目的,并且保证服务过程中的通讯数据是安全的, 类似于 支付宝的支付服务,商家可以申请相应的帐号和私密信息,用于完成支付操作并且保障信息的不可篡改, 但支付宝是通过RSA来校验数据的安全性,而本文是使用md5来校验数据, 客户端与服务端的通讯使用webservice, 以https形式进行交互, 本文假定你已经对axis的webservice的机制和使用有一定的了解

     

【流程】

    1. 客户向平台服务申请AppID(axcpud123)和AppKeySecret(124jfj3ff3AjifLLefl)

    2. 客户准备数据, 数据内容为   telPhone=15261873121, userId=000001, idCert=32132219871234232

       AppID+ & + (用户数据内容按照key名称从小到大排序) + & + AppKeySecret

       对上面的数据进行MD5进行加密码,生成密文 sign

    3. 以axis webservice向服务端发送服务, 服务方法名 为serverMethod

       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是否相同,如果相同,则认为客户端与服务端的通讯数据未被修改


小知道点:

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);  
    }

}


Home